2013-02-09 94 views
3

我無法使用簡單的(?)XSLT轉換進行管理。從平面結構到嵌套的XSLT轉換

有一個輸入扁平結構化的XML:

<root> 
    <attribute_a>abc</attribute_a> 
    <attribute_b>def</attribute_b> 
    <attribute_c>ghi</attribute_c> 
    <attribute_a>123</attribute_a> 
    <attribute_b>456</attribute_b> 
    <attribute_c>789</attribute_c> 
    <attribute_a>xxx</attribute_a> 
    <attribute_b>xxx</attribute_b> 
    <attribute_c>xxx</attribute_c> 
</root> 

我應該把它轉換成一個像這樣的XML:

<root> 
    <attribute> 
     <attribute_a>abc</attribute_a> 
     <attribute_b>def</attribute_b> 
     <attribute_c>ghi</attribute_c> 
    </attribute> 
    <attribute> 
     <attribute_a>123</attribute_a> 
     <attribute_b>456</attribute_b> 
     <attribute_c>789</attribute_c> 
    </attribute> 
    <attribute> 
     <attribute_a>xxx</attribute_a> 
     <attribute_b>xxx</attribute_b> 
     <attribute_c>xxx</attribute_c> 
    </attribute> 
</root> 

但問題是,這樣的改造後:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 

    <xsl:template match="/"> 
     <root> 
      <xsl:for-each select="root/attribute_a"> 
       <attribute> 
        <attribute_a> 
         <xsl:value-of select="../attribute_a" /> 
        </attribute_a> 
        <attribute_b> 
         <xsl:value-of select="../attribute_b" /> 
        </attribute_b> 
        <attribute_c> 
         <xsl:value-of select="../attribute_c" /> 
        </attribute_c> 
       </attribute> 
      </xsl:for-each> 
     </root> 
     <xsl:apply-templates /> 
    </xsl:template> 
</xsl:stylesheet> 

我有這樣的事情:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <attribute> 
     <attribute_a>abc</attribute_a> 
     <attribute_b>def</attribute_b> 
     <attribute_c>ghi</attribute_c> 
    </attribute> 
    <attribute> 
     <attribute_a>abc</attribute_a> 
     <attribute_b>def</attribute_b> 
     <attribute_c>ghi</attribute_c> 
    </attribute> 
    <attribute> 
     <attribute_a>abc</attribute_a> 
     <attribute_b>def</attribute_b> 
     <attribute_c>ghi</attribute_c> 
    </attribute> 
</root> 

我對XSLT不是很有經驗 - 你有什麼想法嗎? :(

問候, AM

+1

歡迎來到SO。感謝一個結構良好的第一個問題。 :) – 2013-02-09 21:08:52

回答

1

這應該做的伎倆:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="/"> 
    <root> 
     <xsl:for-each select="root/attribute_a"> 
     <xsl:variable name="pos" select="position()"/> 
     <attribute> 
      <xsl:apply-templates 
      select="../attribute_a[$pos] | 
        ../attribute_b[$pos] | 
        ../attribute_c[$pos]" /> 
     </attribute> 
     </xsl:for-each> 
    </root> 
    </xsl:template> 
</xsl:stylesheet> 

而且我建議一步服用,並使用單獨的模板,而不是一個for-each的:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="/"> 
    <root> 
     <xsl:apply-templates select="root/attribute_a" mode="group" /> 
    </root> 
    </xsl:template> 

    <xsl:template match="attribute_a" mode="group"> 
    <xsl:variable name="pos" select="position()"/> 
    <attribute> 
     <xsl:apply-templates 
     select="../attribute_a[$pos] | ../attribute_b[$pos] | ../attribute_c[$pos]" /> 
    </attribute> 
    </xsl:template> 
</xsl:stylesheet> 

當這些XSLT中的任何一個在您的示例輸入上運行時,它會生成以下輸出:

<root> 
    <attribute> 
    <attribute_a>abc</attribute_a> 
    <attribute_b>def</attribute_b> 
    <attribute_c>ghi</attribute_c> 
    </attribute> 
    <attribute> 
    <attribute_a>123</attribute_a> 
    <attribute_b>456</attribute_b> 
    <attribute_c>789</attribute_c> 
    </attribute> 
    <attribute> 
    <attribute_a>xxx</attribute_a> 
    <attribute_b>xxx</attribute_b> 
    <attribute_c>xxx</attribute_c> 
    </attribute> 
</root> 
+0

它幫助!非常感謝你! :) – 2013-02-09 21:23:28