2014-04-25 114 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>