如何通过XSLT替换XML属性?将下划线属性转为短横线形式
将XML属性名中的下划线替换为连字符的XSLT方案
没问题,这是个非常典型的XML属性命名格式转换需求,我给你两种不同版本的XSLT实现,你可以根据自己的处理环境选择:
方案1:兼容XSLT 1.0的实现
如果你的工具只支持XSLT 1.0,这个版本的代码兼容性拉满,通过遍历属性重新生成的方式完成替换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配所有XML元素,保留元素本身的名称不变 --> <xsl:template match="*"> <xsl:element name="{name()}"> <!-- 遍历当前元素的每一个属性 --> <xsl:for-each select="@*"> <!-- 把属性名里的下划线替换成连字符,属性值原样保留 --> <xsl:attribute name="{translate(name(), '_', '-')}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <!-- 递归处理子元素,确保整个XML文档的所有属性都被转换 --> <xsl:apply-templates/> </xsl:element> </xsl:template> <!-- 保留文本节点内容不变,避免破坏原有文本 --> <xsl:template match="text()"> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet>
代码细节解释
<xsl:template match="*">:匹配XML里的所有元素,确保每个元素的属性都能被处理到translate(name(), '_', '-'):XSLT 1.0自带的字符替换函数,精准把属性名里的_换成-- 递归处理子元素的逻辑,能保证不管XML嵌套多深,所有层级的属性都会被统一转换
方案2:XSLT 2.0+简化实现
如果你的环境支持XSLT 2.0及以上版本,可以用更直观的replace()函数,代码更简洁:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="*"> <xsl:copy> <!-- 直接用replace函数替换属性名,一步到位 --> <xsl:for-each select="@*"> <xsl:attribute name="{replace(name(), '_', '-')}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>
效果验证
用你给出的示例XML输入:
<class student="TUTORIAL" Book_type="science" num_pages="250" online_license="yes" tag="online library"/>
经过任意一种XSLT转换后,都会得到你需要的结果:
<class student="TUTORIAL" Book-type="science" num-pages="250" online-license="yes" tag="online library"/>
这个方案可以处理任意数量的属性(包括你提到的10-15个),全程只会修改属性名里的下划线,不会影响XML的结构、文本内容和属性值。
内容的提问来源于stack exchange,提问作者Raghava
相关产品推荐
相关产品推荐

