我是一个初学者,我正在尝试使用XSLT 1.0根据相似的类别对XML输入进行分组。这是包含类别和位置的输入xml。输出必须将具有相同类别的所有元素分组并列出唯一的位置:
<?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>
寻找输出为(仅列出按类别分组的唯一位置):
<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>
到目前为止我尝试过的是:
<?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)">
<data>
<category><xsl:value-of select="category"/></category>
<id><xsl:value-of select="id"/></id>
<location><xsl:value-of select="location"/></location></data>
</xsl:for-each>
</xsl:for-each>
</item>
</project>
我实际上得到的是:
<project>
<item>
<data>
<category>gamedata</category>
<id>456</id>
<location>/example/games/data.php</location>
</data>
<data>
<category>gamedata</category>
<id>789</id>
<location>/example/games/score.php</location>
</data>
<data>
<category>gamedata</category>
<id>789</id>
<location>/example/games/score.php</location>
</data>
<data>
<category>gamedata</category>
<id>123</id>
<location>/example/games/data.php</location>
</data>
<data>
<category>gametitle</category>
<id>888</id>
<location>/example/games/title.php</location>
</data>
<data>
<category>gametitle</category>
<id>777</id>
<location>/example/games/title.php</location>
</data>
<data>
<category>gametitle</category>
<id>999</id>
<location>/example/score/title.php</location>
</data>
</item></project>
对于您的嵌套分组问题,我认为您想使用第二个键:
<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="/">
<project>
<item>
<name lang="en">Example</name>
<xsl:for-each select="//Row[generate-id(.) = generate-id(key('keyCategory', category)[1])]">
<data>
<xsl:copy-of
select="category"/>
<xsl:copy-of select="key('keyCategory', category)/id"/>
<xsl:copy-of
select="key('keyCategory', category)[generate-id() = generate-id(key('location', concat(category, '|', location))[1])]/location"/>
</data>
</xsl:for-each>
</item>
</project>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94Acsm4/0
这仅显示分组,并忽略您的输出使用其他名称空间,以便在新名称空间中创建所选元素,我将对其进行转换:
<?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="/">
<project>
<item>
<name lang="en">Example</name>
<xsl:for-each select="//Row[generate-id(.) = generate-id(key('keyCategory', category)[1])]">
<data>
<xsl:apply-templates
select="category"/>
<xsl:apply-templates select="key('keyCategory', category)/id"/>
<xsl:apply-templates
select="key('keyCategory', category)[generate-id() = generate-id(key('location', concat(category, '|', location))[1])]/location"/>
</data>
</xsl:for-each>
</item>
</project>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
是否可以在新行上显示每个位置?这个<xsl:apply-templates select =“ key('keyCategory',category)[generate-id()= generate-id(key('location',concat(category,'|',location))[1]) ] / location“ />在一行中显示难以读取的位置?
由于
<xsl:output indent="yes"/>
输出(包括anylocation
)在xsltfiddle.liberty-development.net/94Acsm4/1上对我来说很合适。您使用哪种XSLT处理器,如何运行它,location
在一行上看到所有s 时如何看待转换结果?我忘记添加了这是我的错误,<xsl:template match =“ *”> <xsl:element name =“ {local-name()}”> <xsl:apply-templates /> </ xsl:element> < / xsl:template>,现在可以正常使用了:)非常感谢。