這可以通過構建身份模板來完成。首先你需要一個模板的接收機元素匹配,複製,但在同一時間加入名屬性
<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>
這也應該輸出相同的結果。我會把它作爲一個練習給讀者它是如何工作的......
下調者應該提及投票的原因!這是一個禮貌!我真的沒有發現任何這個問題的犯規。爲什麼這篇文章被拒絕? –
如果您對Tim的答案感到滿意,那麼請檢查Tim答案左上角的刻度線。這將完成問答過程。 –