2014-04-25 129 views
0

我有哪里是内部的一些部件模块XML ....XSLT 1.0组和计数节点

<?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和计数节点occurancies:

<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> 

我该如何认识到这一点?是否有可能为每个模块动态创建密钥?

回答

4

这是因为你需要包括MODUL 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> 
0

或者,你可以使用内部“MODUL”变量来存储它的@id,并用它目前的“根/ MODUL”过滤器内只有“部分”:

<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>