xml - 是否可以使用 XSLT 1.0 对条目进行分组?
问题描述
我正在研究一种使 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 过滤节点没有帮助,因为我事先不知道数据集是什么。该数据库有数千个活跃客户,硬编码数千个if语句是不合理的。
- 直接用 XSLT 处理数组之类的变量不起作用。我完全按照所写的方式复制粘贴了代码,并且在查看页面时(使用 Google Chrome,托管在本地 WAMPserver 实例上的文件)没有打印任何内容。
由于我们工作环境的限制,升级到 XSLT 2.0 或 3.0 不是一种选择。如果在 XSLT 1.0 中无法解决这个问题,我将不得不完全抛开这整个思路,开始为 PHP 仪表板或其他东西进行宣传。
解决方案
不管这篇文章的评论如何,我们都可以使用另一个Muenchian 示例!,主要是因为分组发生的上下文不同,所以这是为OP量身定做的,根据这篇帖子:https ://stackoverflow.com/a/2334224/1690217
定义密钥解析器,在本例中
customer
为entry
<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>