2011-04-27 67 views
2

我想使用模板來反轉不同的XML序列; 例如:孩子的扭轉順序

<book title="Definitive XML Schema"> 
    <author first="Priscilla" /> 
    <chapter title="[I] "> 
    <section title="[I.1]" /> 
    <section title="[I.2]"> 
     <section title="[I.2.1]" /> 
     <section title="[I.2.2]" /> 
    </section> 
    <section title="[I.3] "> 
     <section title="[I.3.1]" /> 
    </section> 
    </chapter> 
    <chapter title="[II]"> 
    <section title="[II.1]" /> 
    <section title="[II.2]"> 
     <section title="[II.2.1]" /> 
     <section title="[II.2.2]" /> 
    </section> 
    </chapter> 
</book> 

我想要得到這樣的輸出:這是我的XSL。

<?xml version="1.0" encoding="UTF-8"?> 
<book title="Definitive XML Schema"> 
    <author first="Priscilla"/> 
    <chapter title="[I]"> 
     <section title="[I.3]"> 
     <section title="[I.3.1]"/> 
     </section> 
     <section title="[I.2]"> 
     <section title="[I.2.2]"/> 
     <section title="[I.2.1]"/> 
     </section> 
     <section title="[I.1]"/> 
    </chapter> 
    <chapter title="[II]"> 
     <section title="[II.2]"> 
     <section title="[II.2.2]"/> 
     <section title="[II.2.1]"/> 
     </section> 
     <section title="[II.1]"/> 
    </chapter> 
</book> 

是的,這些部分已被顛倒,但章節沒有。

我嘗試使用兩個模板來解決它,但它不能工作..

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:transform version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent ="yes"/> 
<xsl:template match="/"> 
<xsl:apply-templates/> 
<xsl:text>&#10;</xsl:text> 
</xsl:template> 

<xsl:template match="book"> 
    <xsl:copy> 
    <xsl:sequence select="@title"/> 
    <xsl:sequence select="author"/> 
    <xsl:apply-templates select="chapter"> 
    <xsl:with-param name="seq" select="section"/> 

    </xsl:apply-templates> 
    </xsl:copy> 
    </xsl:template> 

<xsl:template match ="chapter|section" as="element()"> 
    <xsl:param name="seq" as="element(section)*"/> 
    <xsl:copy> 
    <xsl:sequence select="@title"/> 
    <xsl:if test="not(empty($seq))"> 
    <xsl:apply-templates select="chapter"> 
     <xsl:with-param name="seq" select="$seq[position()>1]"/> 
    </xsl:apply-templates> 
    <xsl:apply-templates select="$seq[1]"/>  
    </xsl:if> 
    </xsl:copy> 
</xsl:template> 
</xsl:transform> 
+0

我沒有看到第一個和第二個XML之間的任何區別。但是,如果你想多次使用一些不同的模板 - 閱讀模板中的「模式」屬性(http://msdn.microsoft.com/en-us/library/ms256110.aspx) – TOUDIdel 2011-04-27 06:00:34

+0

好問題,+1。請參閱我的答案,瞭解目前呈現的完整且最簡單/最短的解決方案。 :) – 2011-04-28 02:47:20

回答

1

這是一個更簡單的XSLT 1.0(和2.0)解決方案

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="*[section]"> 
    <xsl:copy> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates> 
    <xsl:sort select="position()" 
     data-type="number" order="descending"/> 
    </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被應用在下面的XML文檔:產生

<book title="Definitive XML Schema"> 
    <author first="Priscilla" /> 
    <chapter title="[I] "> 
    <section title="[I.1]" /> 
    <section title="[I.2]"> 
     <section title="[I.2.1]" /> 
     <section title="[I.2.2]" /> 
    </section> 
    <section title="[I.3] "> 
     <section title="[I.3.1]" /> 
    </section> 
    </chapter> 
    <chapter title="[II]"> 
    <section title="[II.1]" /> 
    <section title="[II.2]"> 
     <section title="[II.2.1]" /> 
     <section title="[II.2.2]" /> 
    </section> 
    </chapter> 
</book> 

有用,正確的結果(翻轉section元素的所有序列):

<book title="Definitive XML Schema"> 
    <author first="Priscilla"/> 
    <chapter title="[I] "> 
     <section title="[I.3] "> 
     <section title="[I.3.1]"/> 
     </section> 
     <section title="[I.2]"> 
     <section title="[I.2.2]"/> 
     <section title="[I.2.1]"/> 
     </section> 
     <section title="[I.1]"/> 
    </chapter> 
    <chapter title="[II]"> 
     <section title="[II.2]"> 
     <section title="[II.2.2]"/> 
     <section title="[II.2.1]"/> 
     </section> 
     <section title="[II.1]"/> 
    </chapter> 
</book> 
+0

@Dimitre Novatchev:謝謝你的好回答,如果我不想使用元素,並且想要使用,那我該怎麼辦? – ZAWD 2011-04-28 11:15:01

+0

@ZAWD:''的設計目的是當每個節點的處理結果的期望順序不是默認值時,呈現應用模板(和')的結果的目的文件)命令。如果由於某種無法解釋的原因,您不想使用'',那麼理論上您可以始終處理最後一個元素,然後在部分結果上應用模板。當然,這是非常不合適的。 – 2011-04-28 12:28:30

+0

@Dimitre Novatchev:是的,我試圖用這種方法制作它。創建一個模板並調用它,但它是一個很長的故事,我想使它更短,但沒有 .. :) 1]「/>

ZAWD 2011-04-28 13:40:12

1

這XSLT 2.0樣式表:

<xsl:stylesheet version="2.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="chapter|section"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:apply-templates> 
       <xsl:sort select="tokenize(@title,'.')[last()]" 
          order="descending" 
          data-type="number"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<book title="Definitive XML Schema"> 
    <author first="Priscilla"/> 
    <chapter title="[I] "> 
     <section title="[I.3] "> 
      <section title="[I.3.1]"/></section> 
     <section title="[I.2]"> 
      <section title="[I.2.2]"/> 
      <section title="[I.2.1]"/></section> 
     <section title="[I.1]"/> 
    </chapter> 
    <chapter title="[II]"> 
     <section title="[II.2]"> 
      <section title="[II.2.2]"/> 
      <section title="[II.2.1]"/></section> 
     <section title="[II.1]"/> 
    </chapter> 
</book> 
+0

@Alejandro:爲什麼這樣一個不必要的複雜解決方案? – 2011-04-28 02:49:43

+0

@Alejandro:謝謝你的回答,但我認爲這些部分不會顛倒...... – ZAWD 2011-04-28 11:12:08

+0

@ZAWD:你應該看兩次;) – 2011-04-28 13:06:01