2010-11-15 85 views
1

我在嘗試使用XSLT對XML文檔進行排序,並希望保留註釋。迄今爲止這麼好,因爲這個問題已經有了一些答案(見相關..)。 但是!沒有這些(優秀)答案涉及到一個XML看起來像這樣:現在會發生什麼使用XSLT對XML進行排序,同時保留多條評論

<xml> 
    <beatles> 
     <!-- comment(1): john is actually my favourite --> 
     <!-- comment(2): John died tragically in 1980 --> 
     <beatle name="John"/> 

     <beatle name="Ringo"/> 

     <beatle name="George"/> 

     <!-- comment(1): Paul still does live concerts to this day --> 
     <!-- comment(2): contrary to common folklore, Paul is NOT dead! --> 
     <beatle name="Paul"/> 
    </beatles> 
</xml> 

?我想以按名稱排序甲殼蟲(上帝保佑他們),並保持各甲殼蟲的所有意見的地方,爲了得到這樣的結果:

<xml> 
    <beatles> 
     <beatle name="George"/> 

     <!-- comment(1): john is actually my favourite --> 
     <!-- comment(2): John died tragically in 1980 --> 
     <beatle name="John"/> 

     <!-- comment(1): Paul still does live concerts to this day --> 
     <!-- comment(2): contrary to common folklore, Paul is NOT dead! --> 
     <beatle name="Paul"/> 

     <beatle name="Ringo"/> 
    </beatles> 
</xml> 

好老前同輩::評論( )[1]在這裏不起作用。在常規代碼中,我只是對所有前面的註釋做一個反向循環,當我點擊一個非註釋節點時停止;但衆所周知,XSLT的不能逃脫。

有什麼想法?

TIA!

DF。

+0

好問題,+1。我認爲@ Tim-C給了你一個完美的答案。 – 2010-11-15 13:12:04

回答

0

當複製相應的beatle節點時,您還應該應用其註釋。這就是你需要做的。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="beatles"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:apply-templates select="beatle"> 
       <xsl:sort select="@name" data-type="text"/> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="beatle"> 
     <xsl:variable name="current" select="."/> 
     <xsl:apply-templates 
       select="preceding-sibling::comment()[generate-id(following-sibling::beatle[1]) = generate-id($current)]"/> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 


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

輸出:

<?xml version="1.0" encoding="windows-1251"?> 
<xml> 
    <beatles> 
     <beatle name="George"/> 
     <!-- comment(1): john is actually my favourite --> 
     <!-- comment(2): John died tragically in 1980 --> 
     <beatle name="John"/> 
     <!-- comment(1): Paul still does live concerts to this day --> 
     <!-- comment(2): contrary to common folklore, Paul is NOT dead! --> 
     <beatle name="Paul"/> 
     <beatle name="Ringo"/> 
    </beatles> 
</xml> 
+0

這是我會採取的方法,但如果有11,000披頭士,它將開始表現不佳。 – 2010-11-15 19:28:28

+0

好的形式,每個人!我最終使用了@Alex Nikolaenkov的解決方案,因爲我的問題比訂購相同的節點要複雜一點 - 我有幾個不同的節點,並且必須訂購節點類型組,因此Alex提供的解決方案更合適。 @ Tim-C - 謝謝你的回答,因爲我學到了更多關於XSLT的知識(我昨天才開始學習)。再次感謝所有! – deebugger 2010-11-15 19:31:46

+0

@羅伯特羅斯尼 - 可能是這樣,但我的問題並沒有涉及那麼多的節點,所以我很高興地使用它.. – deebugger 2010-11-15 19:33:30

1

,我認爲這可以通過其中列出了一個給定的「披頭士」元素的所有意見的一個關鍵的手段來實現。

<xsl:key name="comments" match="comment()" use="following-sibling::beatle[1]/@name" /> 

因此,對於每個評論,它都由第一個連續的beatle元素索引。

然後,您可以按如下方式使用它來列出任何beatle元素的所有註釋。

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

    <xsl:key name="comments" match="comment()" use="following-sibling::beatle[1]/@name" /> 

    <xsl:template match="/xml/beatles"> 
     <beatles> 
     <xsl:for-each select="beatle"> 
      <xsl:sort select="@name" /> 

      <!-- Loop through all comments for the beatle element --> 
      <xsl:for-each select="key('comments', @name)"> 
       <xsl:comment> 
        <xsl:value-of select="." /> 
       </xsl:comment> 
      </xsl:for-each> 

      <!-- Copy the beatle element --> 
      <xsl:copy> 
       <xsl:copy-of select="@*" /> 
      </xsl:copy> 
     </xsl:for-each> 
     </beatles> 
    </xsl:template> 

</xsl:stylesheet> 
+0

爲這樣一個簡單的任務使用密鑰的IMO是一個矯枉過正。順便說一下,當使用命令式XSLT時,你會得到更緊密的耦合,並且這些代碼的修改會隨着時間變得越來越難。 – 2010-11-15 09:16:39

+0

+1爲一個完美的答案! – 2010-11-15 13:09:12

+0

@ Alex-Nikolaenkov:鑰匙是正確的情況下的正確工具 - 而且*這種情況是使用鑰匙的最佳選擇。 – 2010-11-15 13:10:23