好的,所以我经历了很多相关的帖子,但未能找到问题的答案。我需要编写一个XSLT来以下列格式转换XML
<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>
到此 -
<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 :(得分:2)
这可以通过构建身份模板来完成。首先,您需要一个模板来匹配 Receiver 元素,复制它,但同时添加名称属性
<xsl:template match="Receiver">
<Receiver name="{name}">
<xsl:apply-templates select="@*|node()"/>
</Receiver>
</xsl:template>
您可以为项元素执行类似的操作。请注意这是如何使用“属性值模板”从name元素的值创建name属性。
然后,您只需要一个模板来匹配名称和没有元素并忽略它们,因此不会输出它们。
<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>
现在,如果你想更通用,并且有一个规则将任何父元素的第一个'leaf'元素转换为属性,那么试试这个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>
这也应该输出相同的结果。我会把它作为练习留给读者如何运作....