我有XML模块,里面有一些部分......
<?xml version="1.0"?>
<root>
<modul id="1">
<part id="01" part_number="AAA"/>
<part id="02" part_number="AAA"/>
<part id="03" part_number="AAA"/>
<part id="04" part_number="BBB"/>
</modul>
<modul id="2">
<part id="05" part_number="AAA"/>
<part id="06" part_number="AAA"/>
<part id="07" part_number="CCC"/>
<part id="08" part_number="BBB"/>
</modul>
</root>
我想在每个模块中按part_number分组并计算节点的出现次数:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyPartNumber" match="part" use="@part_number"/>
<xsl:template match="/">
<xsl:for-each select="root/modul">
<modul name="{@id}">
<xsl:for-each select="part[generate-id() = generate-id(key('keyPartNumber',@part_number)[1])]">
<xsl:sort select="@part_number" order="ascending" data-type="text"/>
<node title="{@part_number} (quantity: {count(key('keyPartNumber',@part_number))})" />
</xsl:for-each>
</modul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
但结果我得到的不是我想要的:
<?xml version="1.0" encoding="UTF-8"?>
<modul name="1">
<node title="AAA (quantity: 5)"/>
<node title="BBB (quantity: 2)"/>
</modul>
<modul name="2">
<node title="CCC (quantity: 1)"/>
</modul>
例外结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<modul name="1">
<node title="AAA (quantity: 3)"/>
<node title="BBB (quantity: 1)"/>
</modul>
<modul name="2">
<node title="AAA (quantity: 2)"/>
<node title="BBB (quantity: 1)"/>
<node title="CCC (quantity: 1)"/>
</modul>
我怎么能意识到这一点?是否可以动态地为每个模块创建密钥?
答案 0 :(得分:5)
这是因为您需要将模块 ID作为键的一部分包含在内,以便部件与模块不同
<xsl:key name="keyPartNumber" match="part" use="concat(../@id, '|', @part_number)"/>
注意|
这里可以是任何内容,只要它不在id或part_number中出现。
您也可以在访问密钥时使用相同的 concat 语句。
试试这个XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyPartNumber" match="part" use="concat(../@id, '|', @part_number)"/>
<xsl:template match="/">
<xsl:for-each select="root/modul">
<modul name="{@id}">
<xsl:for-each select="part[generate-id() = generate-id(key('keyPartNumber',concat(../@id, '|', @part_number))[1])]">
<xsl:sort select="@part_number" order="ascending" data-type="text"/>
<node title="{@part_number} (quantity: {count(key('keyPartNumber',concat(../@id, '|', @part_number)))})" />
</xsl:for-each>
</modul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
或者,您可以在内部使用变量&#34; modul&#34;存储它的@id并用它来过滤那些&#34; part&#34;在当前&#34; root / modul&#34;:
中<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="keyPartNumber" match="part" use="@part_number"/>
<xsl:template match="/">
<root>
<xsl:for-each select="root/modul">
<xsl:variable name="id" select="@id"/>
<modul name="{@id}">
<xsl:for-each select="part[generate-id() = generate-id(key('keyPartNumber',@part_number)[parent::*[@id = $id]][1])]">
<xsl:sort select="@part_number" order="ascending" data-type="text"/>
<node title="{@part_number} (quantity: {count(key('keyPartNumber',@part_number)[parent::*[@id = $id]])})" />
</xsl:for-each>
</modul>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>