2012-12-07 60 views
0

好的,我已經通過許多相關的帖子,但一直沒能找到我的問題的答案。我需要編寫一個XSLT按以下格式處理XSLT中的元素和屬性

<Message> 
    <Receiver> 
     <name>123</name> 
     <address>111</address> 
     <phone>1000</phone> 
    </Receiver> 
    <List> 
     <item> 
     <no>1</no> 
     <desc>one</desc> 
     </item> 
     <item> 
     <no>2</no> 
     <desc>two</desc> 
     </item> 
    </List> 
<Message> 

將XML這個 -

<Message>  
    <Receiver name=123> 
     <address>111</address> 
     <phone>1000</phone> 
    </Receiver> 
    <List> 
     <item no=1> 
      <desc>one</desc> 
     </item> 
     <item no=2> 
      <desc>two</desc> 
     </item> 
    </List> 
</Message> 

我已經使用xsl模板匹配標籤審判。 ,但已慘敗。任何想法或幫助非常感謝/

**注意我已編輯帖子,以顯示實際問題 - 我最初只發布了一部分,以避免混淆,但因爲它似乎需要將問題作爲一個整體說明。對不便之處表示歉意。

+0

下調者應該提及投票的原因!這是一個禮貌!我真的沒有發現任何這個問題的犯規。爲什麼這篇文章被拒絕? –

+0

如果您對Tim的答案感到滿意,那麼請檢查Tim答案左上角的刻度線。這將完成問答過程。 –

回答

2

這可以通過構建身份模板來完成。首先你需要一個模板的接收機元素匹配,複製,但在同一時間加入屬性

<xsl:template match="Receiver"> 
    <Receiver name="{name}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </Receiver> 
</xsl:template> 

你可以做一個類似的項目元素。請注意,這是如何利用「屬性值模板」從名稱元素的值創建名稱屬性的。

然後,你只需要一個模板來匹配沒有元素,而忽略他們,因此他們不會輸出。

<xsl:template match="name|no" /> 

以下是完整的XSLT

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

    <xsl:template match="Receiver"> 
     <Receiver name="{name}"> 
      <xsl:apply-templates select="@*|node()"/> 
     </Receiver> 
    </xsl:template> 

    <xsl:template match="item"> 
     <item no="{no}"> 
      <xsl:apply-templates select="@*|node()"/> 
     </item> 
    </xsl:template> 

    <xsl:template match="name|no" /> 

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

當適用於您的XML輸出以下

<Message> 
    <Receiver name="123"> 
     <address>111</address> 
     <phone>1000</phone> 
    </Receiver> 
    <List> 
     <item no="1"> 
     <desc>one</desc> 
     </item> 
     <item no="2"> 
     <desc>two</desc> 
     </item> 
    </List> 
</Message> 

現在,如果你想成爲更通用,並且有一個規則,其中任何父元素的第一個「葉」元素變成屬性,然後試試這個XSLT

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

    <xsl:template match="*[*[1][not(*)]]"> 
     <xsl:copy> 
      <xsl:attribute name="{name(*[1])}"> 
       <xsl:value-of select="*"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="*/*[1][not(*)]"/> 

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

這也應該輸出相同的結果。我會把它作爲一個練習給讀者它是如何工作的......

+0

感謝您的快速答覆 - 因爲我的原始要求是節點在另一個節點內部,名爲,當我在標籤內實現上述代碼時,這又不起作用 - 是否有一種特定的方式將上述內容包含在標籤? –

+1

如果你可以修改你的原始問題來表明這一點,那麼它聽起來很簡單,足以實現。謝謝! –

+0

謝謝。我會嘗試這兩種方法。 –

相關問題