[英]Handling Elements and Attributes in XSLT
好的,所以我经历了许多相关的帖子,但未能找到我的问题的答案。 我需要编写一个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模板匹配标记。 但是悲惨地失败了。 任何想法或帮助非常感谢/
**注意我已编辑帖子以显示实际问题 - 我最初只发布了一部分以避免混淆,但因为它似乎需要整体说明问题。 抱歉给您带来不便。
这可以通过构建身份模板来完成。 首先,您需要一个模板来匹配Receiver元素,复制它,但同时添加name属性
<xsl:template match="Receiver">
<Receiver name="{name}">
<xsl:apply-templates select="@*|node()"/>
</Receiver>
</xsl:template>
您可以为item元素执行类似的操作。 请注意这是如何使用“属性值模板”从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>
这也应该输出相同的结果。 我会把它作为练习留给读者如何运作....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.