如何使用XSL根据XML的header值动态重命名data区域内的元素
实现方案
核心逻辑
你要的效果可以通过XSLT的动态元素生成能力非常简洁地实现,不需要复杂的循环逻辑:
- 用
<xsl:element>指令可以动态生成自定义名称的XML节点 - 按位置一一对应
<heading>标签和<item>下的<elmN>节点 - 替换
<heading>文本中的空格为下划线,生成合法的XML元素名
完整代码实现
XSLT 2.0及以上版本(最简便,支持现代XSLT处理器)
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 配置输出格式:缩进、省略XML声明 --> <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> <!-- 预存所有heading节点,方便后续按位置读取 --> <xsl:variable name="headers" select="/root/headers/heading"/> <!-- 匹配根节点,直接输出外层data标签 --> <xsl:template match="/root"> <data> <xsl:apply-templates select="data/item"/> </data> </xsl:template> <!-- 处理每个item节点 --> <xsl:template match="item"> <item> <!-- 遍历当前item下的所有elm子节点 --> <xsl:for-each select="*"> <!-- 取同位置的heading文本,替换空格为下划线作为新标签名 --> <xsl:variable name="tagName" select="replace($headers[position() = current()/position()], ' ', '_')"/> <!-- 生成新节点,复制原节点的内容 --> <xsl:element name="{$tagName}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </item> </xsl:template> </xsl:stylesheet>
XSLT 1.0兼容版本(适配旧版本处理器)
如果你的运行环境只支持XSLT 1.0,没有replace函数,只需要把上面代码中生成tagName的行替换为使用translate函数即可,其余代码完全不变:
<xsl:variable name="tagName" select="translate($headers[position() = current()/position()], ' ', '_')"/>
效果验证
使用你提供的原始XML作为输入,上述代码转换后的输出和你给出的理想结果完全一致。
内容的提问来源于stack exchange,提问作者devforweb_17
相关产品推荐
相关产品推荐

