2015-02-06 61 views
0

我是新來的XSL和麪臨的問題,以組相同名稱的XML元素。 這裏是我的輸入XML元素問題與子節點分組

<Products> 
<Product type='Item' id='111'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
    </Group1> 
    <Group1> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
    </Group2> 
    <Group2> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
     </Group1> 
     <Group1> 
      <color>Green</color> 
       <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
     </Group2> 
     <Group2> 
      <color>White</color> 
       <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
<Product type='Item' id='222'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
    </Group1> 
    <Group1> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
    </Group2> 
    <Group2> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
     </Group1> 
     <Group1> 
      <color>Green</color> 
       <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
     </Group2> 
     <Group2> 
      <color>White</color> 
       <item>yyy</item> 
     </Group2> 
    </Product> 
</Products> 

我們正在試圖讓輸出如下:

<Products> 
<Product type='Item' id='111'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
      <color>Green</color> 
      <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
      <color>White</color> 
      <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
<Product type='Item' id='222'> 
    <Group1> 
     <color>Blue</color> 
     <item>xxx</item> 
     <color>Green</color> 
      <item>yyy</item> 
    </Group1> 
    <Group2> 
     <color>Yellow</color> 
     <item>xxx</item> 
     <color>White</color> 
      <item>yyy</item> 
    </Group2> 
    <Product type='ChildItem'> 
     <Group1> 
      <color>Blue</color> 
      <item>xxx</item> 
      <color>Green</color> 
      <item>yyy</item> 
     </Group1> 
     <Group2> 
      <color>Yellow</color> 
      <item>xxx</item> 
      <color>White</color> 
      <item>yyy</item> 
     </Group2> 
    </Product> 
</Product> 
</Products> 

現在用下面的XSL文件進行轉換,但由於預期沒有得到輸出

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:key name="elements" match="/Product/*" use="name()"/> 
<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:for-each select="*[count(. | key('elements', name())[1]) = 1]"> 
      <xsl:copy> 
       <xsl:apply-templates select="key('elements', name())/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

回答

1

您按名稱對Product的子元素進行分組,但是此分組需要分別爲每個產品完成,因此您需要參考Product是關鍵用法

<xsl:key name="elements" 
     match="Product/*[not(self::Product)]" 
     use="concat(name(), '|', generate-id(..))"/> 

注意如何的關鍵比賽沒有/前綴,否則只會匹配稱爲Product根元素,其將匹配在沒有你的情況。還注意到它只與非Product元素相匹配。

(並且還沒有產生一個唯一的ID爲Product元素使用generate-id()來標識)

接下來,你需要改變你的第二個模板匹配Product,不\*因爲\*只會匹配根元素。那麼這個模板中,你得到的分組元素,像這樣:

<xsl:for-each 
    select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]"> 

試試這個XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:key name="elements" match="Product/*[not(self::Product)]" use="concat(name(), '|', generate-id(..))"/> 

<xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Product"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:for-each select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]"> 
      <xsl:copy> 
       <xsl:apply-templates select="key('elements', concat(name(), '|', generate-id(..)))/*"/> 
      </xsl:copy> 
     </xsl:for-each> 
     <xsl:apply-templates select="Product" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 
+0

非常感謝......它的工作 – 2015-02-06 09:26:38

+0

@BhavyaV請不要忘記[接受這個答案] (http://stackoverflow.com/help/someone-answers)如果它解決了你的問題。謝謝! – 2015-02-06 16:44:21

+0

尼斯分組碼,+1。 – 2015-02-06 16:45:38