2014-06-19 24 views
1

我想使用XSLT將XML文件的一部分移動到另一個節點。 我只想移動開始某個節點的所有內容。 最好通過一個例子來解釋。從某個節點開始的XSLT複製

這將是輸入XML(它只是一個樣本)

<Messages> 
    <Message> 
    <Header> 
     <Name>Message Content 1</Name> 
    </Header> 
    <Info1> 
     <Description>blabla</Description> 
    </Info1> 
    <Info2> 
     <Name>Test</Name> 
     <Description>blabla</Description> 
    </Info2> 
    ... Possible more nodes (with random names) 
    <Header> 
     <Name>Message Content Summary</Name> 
    </Header> 
    <Info1> 
     <Total>blablabla</Total> 
    </Info1> 
    ... Possible more nodes (with random names) 
    </Message> 
</Messages> 

我想獲得以下輸出:

<Messages> 
    <Message> 
    <Header> 
     <Name>Message Content 1</Name> 
    </Header> 
    <Info1> 
     <Description>blabla</Description> 
    </Info1> 
    <Info2> 
     <Name>Test</Name> 
     <Description>blabla</Description> 
    </Info2> 
    ... Possible more nodes (with random names) 
    </Message> 
    <MessageSummary> 
    <Header> 
     <Name>Message Content Summary</Name> 
    </Header> 
    <Info1> 
     <Total>blablabla</Total> 
    </Info1> 
    ... Possible more nodes (with random names) 
    </MessageSummary> 
</Messages> 

所以我想移動一切從最後一次出現開始將節點「Header」分解爲單獨的節點「MessageSummary」。

有什麼辦法可以使用XSLT 1.0來完成這個任務嗎? 任何幫助將不勝感激。

謝謝。

回答

2

所以,當你在輸入Message元素的情況下,你想放有後至少一個Header到輸出Message和裏面的一切MessageSummary其他任何元素。您可以區分這兩種情況*[following-sibling::Header]*[not(following-sibling::Header)],所以如果我們從一個標準的身份轉換,我們結束了

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

    <!-- identity template - copies everything as-is unless overridden --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy> 
    </xsl:template> 

    <xsl:template match="Message"> 
    <xsl:copy> 
     <xsl:apply-templates select="*[following-sibling::Header]" /> 
    </xsl:copy> 
    <MessageSummary> 
     <xsl:apply-templates select="*[not(following-sibling::Header)]" /> 
    </MessageSummary> 
    </xsl:template> 
</xsl:stylesheet> 

如果您有其他元素命名爲「隨機的名字」部分中,您可能希望使Message啓動這個模板更具體,例如

<xsl:template match="Messages/Message"> 

所以它只捕捉你真正想要的元素。

+0

嗨,謝謝你的建議。我修改了一下,所以第一個副本選擇* [following-sibling :: Header [1]] ==>需要複製第一個頭部下的所有項目。第二個副本選擇:* [not(after-sibling :: Header [2])] ==>第二個標題下的所有項目都需要複製到摘要節點。它似乎工作正常:) –

+0

@Rise_against不會完全做你所描述的,因爲兄弟姐妹軸上的數字謂詞計算兄弟姐妹 - '* [not(following-sibling :: Header [2])]'find all all elements在它們之後至少有兩個標題,所以在倒數第二個標題之前的元素,而不是第二個標題。如果你想使用第二個標題作爲截斷點,那麼你需要像第一部分的'Header [2]/preceding-sibling :: *'和'Header [2] |第二個是[Header [2]/following-sibling :: *']。 –

+0

嗨伊恩,你是對的!忘記我最後一句話,你的解決方案正常工作!起初它不起作用是我的錯(在XSLT中做了一些拼寫錯誤)。但糾正後,它按預期工作。再次感謝您的幫助! –