如何在XSLT中动态提取XML attributes子节点的元素名?
问题
给定如下XML输入文档:
<root> <type>abc</type> <data> <attributes> <atr1> <values>val1</values> </atr1> <atr2> <values>val2</values> </atr2> . . </attributes> </data> </root>
其中attributes的子节点(如atr1、atr2等)是动态变化的,需要动态提取这些子节点的元素名,并生成指定结构的XML输出。当前使用的XSLT代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" method="xml" omit-xml-declaration="yes" /> <xsl:template match="/"> <root> <type> <xsl:value-of select="root/type" /> </type> <Attributes> <xsl:for-each select="root/data/attributes"> <Attribute> <xsl:attribute name="id"> <xsl:value-of select="name(.)" /> </xsl:attribute> <values> <xsl:value-of select="attributes/values/value" /> </values> </Attribute> </xsl:for-each> </Attributes> </root> </xsl:template> </xsl:stylesheet>
期望的更新后输出结构为:
<root> <type/> <attributes> <attribute param="atr1"> <value/> </attribute> <attribute param="atr2"> <value/> </attribute> .. </attributes> </root>
解决方案
核心问题分析
当前代码的问题点:
xsl:for-each选择的是root/data/attributes节点本身,而非它的动态子节点,无法遍历atr1、atr2这类元素。name(.)获取的是attributes节点的名称,不是目标子节点的名称。- 取值路径错误,原输入中只有
values节点,不存在value节点。
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" method="xml" omit-xml-declaration="yes" /> <xsl:template match="/"> <root> <type> <xsl:value-of select="root/type" /> </type> <attributes> <!-- 遍历attributes下的所有直接子节点 --> <xsl:for-each select="root/data/attributes/*"> <attribute> <!-- 获取当前子节点的名称作为param属性值 --> <xsl:attribute name="param"> <xsl:value-of select="name(.)" /> </xsl:attribute> <!-- 提取values节点内容到value节点 --> <value> <xsl:value-of select="values" /> </value> </attribute> </xsl:for-each> </attributes> </root> </xsl:template> </xsl:stylesheet>
关键说明
- 动态遍历子节点:使用
root/data/attributes/*选择attributes下的所有直接子元素,无论节点名称是什么,都能自动遍历。 - 提取节点名称:在
xsl:for-each循环内,name(.)会获取当前遍历到的子节点(如atr1、atr2)的名称,直接赋值给param属性。 - 值的映射:原输入中每个动态子节点下是
values节点,直接通过select="values"获取其文本内容,放入输出的value节点中。
最终输出示例
应用上述XSLT后,输入文档会生成如下输出:
<root> <type>abc</type> <attributes> <attribute param="atr1"> <value>val1</value> </attribute> <attribute param="atr2"> <value>val2</value> </attribute> </attributes> </root>
内容的提问来源于stack exchange,提问作者stels
相关产品推荐
相关产品推荐

