2011-09-09 106 views
3

有沒有辦法將父標籤添加到現有的一組節點?向現有元素添加父標記?

例子:

<root> 
<c> 
    <d></d> 
<e> 
    <f></f> 
</e> 
<b></b> 
<b></b> 
<b></b> 
</c> 
</root> 

所需的輸出:

<root> 
    <c> 
     <d></d> 
    <e> 
     <f></f> 
    </e> 
    <a> 
    <b></b> 
    <b></b> 
    <b></b> 
    </a> 
</c> 
    </root> 

謝謝!

+0

問得好,+1。看到我的答案是比目前接受的解決方案更通用的解決方案。我的解決方案將'a'中的每個*組'b'包裝起來。 –

回答

3

@ EMPO的答案只能在非常簡單的情況下,而不是像這樣的XML文檔

<root> 
    <c> 
     <d></d> 
     <e> 
      <f></f> 
     </e> 
     <b></b> 
     <b></b> 
     <b></b> 
    </c> 
    <b></b> 
    <b></b> 
</root> 

在這裏,如果我們想要一個a,單程內包裝組連續b s到實現這一目標是

<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:key name="kFollowing" match="b" 
    use="generate-id(preceding-sibling::*[not(self::b)][1])"/> 

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

<xsl:template match="b[not(preceding-sibling::*[1][self::b])]"> 
    <a> 
    <xsl:copy-of select= 
    "key('kFollowing', generate-id(preceding-sibling::*[1]))"/> 
    </a> 
</xsl:template> 
<xsl:template match="b"/> 
</xsl:stylesheet> 

當這種轉變是在上面的XML文檔應用中,希望正確的結果(連續b一切都組包裹在a)產生

<root> 
    <c> 
     <d/> 
     <e> 
     <f/> 
     </e> 
     <a> 
     <b/> 
     <b/> 
     <b/> 
     </a> 
    </c> 
    <a> 
     <b/> 
     <b/> 
    </a> 
</root> 
+0

是的,你是對的。我在回答中指出,OP只有在其樣本反映其實際情況時才能使用它。我沒有時間思考一個通用的解決方案。但是,您認爲的例子可能對OP沒有意義。 –

+0

@empo:當然。只要有可能,我會嘗試提供解決方案,解決具體問題,並且如果可能的話,還會解決一類類似的問題。我相信這樣的解決方案更有價值。 –

+0

我完全同意。 +1 –

1

你可以使用一個恆等變換,並做到這一點:

<xsl:template match="root"> 
    <root> 
     <a> 
     <xsl:apply-templates/> 
     </a> 
    </root> 
    </xsl:template> 

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

這將工作,但我需要它在一個XML中,我讓我的例子太簡單了。見上面的編輯。 – DurkD

2

希望您的XML現在反映好多了你的真實情況下,你可以使用:

<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/c/b[1]"> 
     <a> 
      <xsl:copy-of select="self::*|following::b"/> 
     </a> 
    </xsl:template> 

    <xsl:template match="b"/> 

</xsl:stylesheet> 
+1

工作出色!謝謝! – DurkD