是否可以使用 XSLT 1.0 对条目进行分组?

Posted

技术标签:

【中文标题】是否可以使用 XSLT 1.0 对条目进行分组?【英文标题】:Is it possible to group entries using XSLT 1.0? 【发布时间】:2021-11-08 08:49:55 【问题描述】:

我正在研究一种使 XML 选择列表更易于阅读的方法。数据看起来像这样:

<data>
  <entry>
    <customer>Acme</customer>
    <sku>123123</sku>
    <desc>Name Of First Product</desc>
  </entry>
  <entry>
    <customer>GeneriCo</customer>
    <sku>456456</sku>
    <desc>Name Of Second Product</desc>
  </entry>
  <entry>
    <customer>Acme</customer>
    <sku>789789</sku>
    <desc>Name Of Third Product</desc>
  </entry>
</data>

我要做的是过滤数据,以便将每个客户订购的所有产品组合在一起(客户不一定需要排序)。像这样的:

Acme:
    123123 Name of First Product
    789789 Name of Third Product

GeneriCo:
    456456 Name of Second Product

我已经看过的问题:

XSLT filtering nodes on conditional logic 没有帮助,因为我事先不知道数据集是什么。该数据库有数千个活跃客户,硬编码数千个 if 语句是不合理的。 Handling array like variable with XSLT 直线上升不起作用。我完全按照所写的方式复制粘贴了代码,并且在查看页面时(使用 Google Chrome,文件托管在本地 WAMPserver 实例上)没有打印出来。

由于我们工作环境的限制,不能选择升级到 XSLT 2.0 或 3.0。如果在 XSLT 1.0 中无法解决这个问题,我将不得不完全抛开这整个思路,开始为 php 仪表板或其他东西进行宣传。

【问题讨论】:

这个比较简单,只要看看这篇文章的所有相关问题来获得灵感。发布您的 XSL,我们可以帮助您进行调试,只需在查询上应用模板即可。 XSLT 1.0 中的分组最好使用 Muenchian 方法:jenitennison.com/xslt/grouping/muenchian.html。您可以在这些页面上找到大量的 Muenchian 分组示例 - 这里只是一个:***.com/a/37822566/3016153 【参考方案1】:

不管this post's comment,我们都可以用另一个Muenchian example!,主要是分组发生的上下文不同,所以这是为OP量身定做的,基于这篇帖子:https://***.com/a/2334224/1690217

    定义密钥解析器,在本例中为 entry 上的 customer 元素

    <xsl:key name="customers" match="entry" use="customer" />
    

    选择唯一的分组值

    <xsl:apply-templates select="data/entry[generate-id()=generate-id(key('customers',customer)[1])]"/>
    

    为每个元素定义模板,在本例中为条目

     <xsl:template match="entry">
         <h1>
             <xsl:value-of select="customer"/>
         </h1>
         <table id="customer">
             <tr class="heading">
                 <th scope="col">SKU</th>
                 <th scope="col">Description</th>
             </tr>
             <xsl:for-each select="key('customers', customer)">
                 <tr>
                     <td>
                         <xsl:value-of select="sku"/>
                     </td>
                     <td>
                         <xsl:value-of select="desc"/>
                     </td>
                 </tr>
             </xsl:for-each>
         </table>
     </xsl:template>
    

查看实际操作:http://xsltransform.net/nc4P6y1/3

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

    <xsl:key name="customers" match="entry" use="customer" />
    
    <xsl:template match="entry">
        <h1>
            <xsl:value-of select="customer"/>
        </h1>
        <table id="customer">
            <tr class="heading">
                <th scope="col">SKU</th>
                <th scope="col">Description</th>
            </tr>
            <xsl:for-each select="key('customers', customer)">
                <tr>
                    <td>
                        <xsl:value-of select="sku"/>
                    </td>
                    <td>
                        <xsl:value-of select="desc"/>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
    
    <xsl:template match="/">
      <html>
        <head>
          <title>Group By Customer</title>
        </head>
        <body>
            <xsl:apply-templates select="data/entry[generate-id()=generate-id(key('customers',customer)[1])]"/>
        </body>
      </html>
    </xsl:template>
    
</xsl:transform>

<!DOCTYPE html
  PUBLIC "XSLT-compat">
<html>
   <head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Group By Customer</title>
   </head>
   <body>
  <h1>Acme</h1>
  <table id="Acme">
     <tr class="heading">
        <th scope="col">SKU</th>
        <th scope="col">Description</th>
     </tr>
     <tr>
        <td>123123</td>
        <td>Name Of First Product</td>
     </tr>
     <tr>
        <td>789789</td>
        <td>Name Of Third Product</td>
     </tr>
  </table>
  <h1>GeneriCo</h1>
  <table id="GeneriCo">
     <tr class="heading">
        <th scope="col">SKU</th>
        <th scope="col">Description</th>
     </tr>
     <tr>
        <td>456456</td>
        <td>Name Of Second Product</td>
     </tr>
  </table>
   </body>
</html>

【讨论】:

以上是关于是否可以使用 XSLT 1.0 对条目进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

基于列表中的日期字段,在每一天对使用XSLT 1.0的列表进行分组

使用 XSLT 对 HTML 输出进行分组(muenchian 分组?)

如何在下面的 XSLT 1.0 代码中进行分组。需要按 TaxRateCode 分组

XSLT 1.0 按子节点的值对 xml 节点进行分组

使用 XSLT 程序对具有逗号分隔值的 XML 元素进行分组

我无法理解 XSLT 1.0 Muenchian 分组