XSLT beginner: Group XML based on unique element value XSLT 1.0
我是一个初学者,我正在尝试使用 XSLT 1.0 对基于类似类别的 XML 输入进行分组。这是包含类别和位置的输入 xml。输出必须将所有具有相同类别的元素分组并列出唯一位置:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version=“1.0” ?>
<Data> <Row> <id>123</id> <location>/example/games/data.php</location> <category>gamedata</category> </Row> <Row> <id>456</id> <location>/example/games/data.php</location> <category>gamedata</category> </Row> <Row> <id>789</id> <location>/example/games/score.php</location> <category>gamedata</category> </Row> <Row> <id>888</id> <location>/example/games/title.php</location> <category>gametitle</category> </Row> <Row> <id>777</id> <location>/example/games/title.php</location> <category>gametitle</category> </Row> <Row> <id>999</id> <location>/example/score/title.php</location> <category>gametitle</category> </Row> </Data> |
寻找输出(仅列出按类别分组的唯一位置):
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<project>
<item> <data> <category>gamedata</category> <id>456</id> <id>789</id> <id>123</id> <location>/example/games/data.php</location> <location>/example/games/score.php</location> </data> <data> <category>gametitle</category> <id>888</id> <id>777</id> <id>999</id> <location>/example/games/title.php</location> <location>/example/score/title.php</location> </data> </item></project> |
到目前为止我尝试过的:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version=“1.0” encoding=“UTF-8”?>
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”> <xsl:key name=“keyCategory” match=“Row” use=“category”/> <xsl:template match=“/”> <project xmlns=“xyz.com”> <item > <name lang=“en”>Example</name> <xsl:for-each select=“//Row[generate-id(.) = generate-id(key(‘keyCategory’, category)[1])]”> <xsl:for-each select=“key(‘keyCategory’, category)”> |
我实际上得到了什么:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<project>
<item> <data> <category>gamedata</category> <id>456</id> <location>/example/games/data.php</location> </data> </data> </data> </data> </data> </data> </data> |
- 如果您想对分组元素进行分组和package,那么显然您的package器(例如 data)需要在 <xsl:for-each select=”//Row[generate-id(.) = generate-id(key(‘keyCategory’, category)[1])]”> 内部使用,例如<xsl:for-each select=”//Row[generate-id(.) = generate-id(key(‘keyCategory’, category)[1])]”><data>…</data></xsl:for-each>。如果您还想识别每个组中的唯一位置,那么您需要第二个密钥或一些特定于处理器的扩展方法。
- @MartinHonnen 非常感谢它现在按照您的建议工作。
对于您的嵌套分组问题,我认为您想使用第二个键:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”>
<xsl:output indent=“yes”/> <xsl:key name=“keyCategory” match=“Row” use=“category”/> <xsl:key name=“location” match=“Row” use=“concat(category, ‘|’, location)”/> <xsl:template match=“/”> |
https://xsltfiddle.liberty-development.net/94Acsm4/0
这仅显示分组并忽略您的输出使用不同的命名空间,为了在新命名空间中创建所选元素,我将对其进行转换:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<?xml version=“1.0” encoding=“UTF-8”?>
<xsl:stylesheet version=“1.0” xmlns:xsl=“http://www.w3.org/1999/XSL/Transform” xmlns=“http://example.com/”> <xsl:output indent=“yes”/> <xsl:key name=“keyCategory” match=“Row” use=“category”/> <xsl:key name=“location” match=“Row” use=“concat(category, ‘|’, location)”/> <xsl:template match=“/”> <xsl:template match=“*”> |
https://xsltfiddle.liberty-development.net/94Acsm4/1
- 是否可以在新行上显示每个位置? this <xsl:apply-templates select=”key(\\’keyCategory\\’, category)[generate-id() = generate-id(key(\\’location\\’, concat(category, \\’|\\’, location))[1])]/location”/> 在一行中显示难以阅读的位置?
- 由于 <xsl:output indent=”yes”/>,输出(包括任何 location)在 xsltfiddle.liberty-development.net/94Acsm4/1 上对我来说很好地缩进了。您使用哪个 XSLT 处理器,如何运行它,当您看到一行中的所有 location 时,您如何看待转换结果?
- 这是我的错误,我忘了添加,<xsl:template match=”*”> <xsl:element name=”{local-name()}”> <xsl:apply-templates/> </xsl :element> </xsl:template> 现在它工作得很好:) 非常感谢。
来源:https://www.codenong.com/60025839/