2011-04-27 91 views
5

我正在使用標識轉換,並且在此期間基於條件,我需要使用XSLT更改節點的位置。 想,我有一個像這樣的XML:使用XSLT更改節點的位置

<root> 
    <a> 
     <b1>SampleB1</b1> 
     <b2> 
      <c1>zyx</c1> 
      <c2>wvu</c2> 
      <c3>tsr</c3> 
      <c4>dtg</c4> 
      <c5>hkj</c5> 
     </b2> 
     <b3>SampleB3</b3> 
    </a> 
</root> 

然後我想改變節點「C4」 &「C5」的位置,並希望輸出爲:

<root> 
    <c4>dtg</c4> 
    <c5>hkj</c5> 
    <a> 
     <b1>SampleB1</b1> 
     <b2> 
      <c1>zyx</c1> 
      <c2>wvu</c2> 
      <c3>tsr</c3> 
     </b2> 
     <b3>SampleB3</b3> 
    </a> 
</root> 

誰能告訴我,我們怎麼做到這一點。

謝謝!

回答

0

要重新排列,您需要調整您的XSL,以便它按您想要的順序和位置複製您想要的內容。例如:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- At the root element, recurse through any descendant c4 or c5 nodes first --> 
    <xsl:template match="root"> 
     <xsl:copy> 
      <xsl:apply-templates select="//c4|//c5"/> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <!-- At the b2 element, copy everything but the C4 or C5 nodes --> 
    <xsl:template match="b2"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()[not(self::c4|self::c5)]|@*"/> 
     </xsl:copy> 
    </xsl:template> 

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

</xsl:stylesheet> 
+0

對於'b2'規則的內容模板,''xsl:apply-templates select =「node()[not(self :: c4 | self :: c5)] | @ *」/>'會更好。 – 2011-04-27 17:36:54

+0

謝謝Erica。有用 !!! – Piyush 2011-04-28 12:29:20

1

試試這個:

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

    <!-- By default, recursively copy all nodes unchanged --> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <!-- But don't copy root/a/b2/c3 and root/a/b2/c4 --> 
    <xsl:template match="root/a/b2/c3" /> 
    <xsl:template match="root/a/b2/c4" /> 

    <xsl:template match="root"> 
    <xsl:copy> 
     <!-- Place a copy of a/b2/c3 and a/b2/c4 at the start of root --> 
     <xsl:copy-of select="a/b2/c3" /> 
     <xsl:copy-of select="a/b2/c4" /> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

上述理解的關鍵是,它不是移動元素這麼多複製元素,然後在其他地方跳過他們。不幸的是,這意味着我們需要指定要移動的元素兩次(一次跳過它們,然後再次在其他地方包含它們的副本),但目前我無法想到一個更好的方法。

這個問題 - Move sub nodes into parent attributes with XSLT也可能有幫助。

+0

感謝Kragen!我的情況下,您的解決方案不起作用,因爲我正在更新根節點和父節點。 – Piyush 2011-04-28 12:27:04

1

純拉風:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="a"> 
     <xsl:apply-templates mode="search"/> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
    <xsl:template match="c4|c5"/> 
    <xsl:template match="c4|c5" mode="search"> 
     <xsl:call-template name="identity"/> 
    </xsl:template> 
    <xsl:template match="text()" mode="search"/> 
</xsl:stylesheet> 

輸出:

<root> 
    <c4>dtg</c4> 
    <c5>hkj</c5> 
    <a> 
     <b1>SampleB1</b1> 
     <b2> 
      <c1>zyx</c1> 
      <c2>wvu</c2> 
      <c3>tsr</c3> 
     </b2> 
     <b3>SampleB3</b3> 
    </a> 
</root>