2015-03-13 139 views
0

我想在父標記(<Item>)以及子標記(<Sku>)中對具有相同名稱的節點進行分組。xslt組在父節點以及子節點下的相同節點

<Item>標籤可能包含許多<Sku>子標籤,但這些不應該在每一個Sku進行分組,而元素和Item應單獨分組。

我有一個輸入XML文件,如下圖所示:

<Products> 
    <Item> 
    <Dimensions> 
     <Height>10</Height> 
    </Dimensions> 
    <Dimensions> 
     <Weight>10</Weight> 
    </Dimensions> 
    <Color> 
     <Attribute>Orange</Attribute> 
    </Color> 
    <Color> 
     <Attribute>Blue</Attribute> 
    </Color> 
    <Sku> 
    <Dimensions> 
     <Height>10</Height> 
    </Dimensions> 
    <Dimensions> 
     <Weight>10</Weight> 
    </Dimensions> 
    <Color> 
     <Attribute>Orange</Attribute> 
    </Color> 
    <Color> 
     <Attribute>Blue</Attribute> 
    </Color> 
    </Sku> 
    <Sku> 
    <Dimensions> 
     <Height>10</Height> 
    </Dimensions> 
    <Dimensions> 
     <Weight>10</Weight> 
    </Dimensions> 
    <Color> 
     <Attribute>Orange</Attribute> 
    </Color> 
    <Color> 
     <Attribute>Blue</Attribute> 
    </Color> 
    </Sku> 
    </Item> 
</Products> 

輸出預計爲象下面這樣:

<Products> 
    <Item> 
     <Dimensions> 
      <Height>10</Height> 
      <Weight>10</Weight> 
     </Dimensions> 
     <Color> 
      <Attribute>Orange</Attribute> 
      <Attribute>Blue</Attribute> 
     </Color> 
     <Sku> 
     <Dimensions> 
      <Height>10</Height> 
      <Weight>10</Weight> 
     </Dimensions> 
     <Color> 
      <Attribute>Orange</Attribute> 
      <Attribute>Blue</Attribute> 
     </Color> 
    </Sku> 
    <Sku> 
     <Dimensions> 
      <Height>10</Height> 
      <Weight>10</Weight> 
     </Dimensions> 
     <Color> 
      <Attribute>Orange</Attribute> 
      <Attribute>Blue</Attribute> 
     </Color> 
    </Sku> 
    </Item> 
</Products> 

任何幫助將不勝感激。 我已經使用了下面的xslt進行轉換,但它只是在「Item」下面顯示元素。

<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="Item/*[not(self::Sku)]" use="concat(name(), '|', generate-id(..))"/> 

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

<xsl:template match="Item"> 
    <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="Item" /> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

回答

0

可以共享相同的邏輯兩個集團之間,就像這樣:

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

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

    <xsl:template name="GroupChildren"> 
    <xsl:param name="elements" select="*" /> 

    <xsl:for-each select="$elements[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:template> 

    <xsl:template match="Item"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:call-template name="GroupChildren"> 
     <xsl:with-param name="elements" select="*[not(self::Sku)]" /> 
     </xsl:call-template> 
     <xsl:apply-templates select="Sku" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Sku"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:call-template name="GroupChildren" /> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

當你的樣品輸入運行,其結果是:

<Products> 
    <Item> 
    <Dimensions> 
     <Height>10</Height> 
     <Weight>10</Weight> 
    </Dimensions> 
    <Color> 
     <Attribute>Orange</Attribute> 
     <Attribute>Blue</Attribute> 
    </Color> 
    <Sku> 
     <Dimensions> 
     <Height>10</Height> 
     <Weight>10</Weight> 
     </Dimensions> 
     <Color> 
     <Attribute>Orange</Attribute> 
     <Attribute>Blue</Attribute> 
     </Color> 
    </Sku> 
    <Sku> 
     <Dimensions> 
     <Height>10</Height> 
     <Weight>10</Weight> 
     </Dimensions> 
     <Color> 
     <Attribute>Orange</Attribute> 
     <Attribute>Blue</Attribute> 
     </Color> 
    </Sku> 
    </Item> 
</Products>