仅在XML特定位置转换实体的XSLT样式表问题排查
解决XSLT3.0反转义XML实体的两个问题
问题分析
当前XSLT存在两个核心问题:
- 错误将所有原生
-字符转成‐实体,实际仅需将输入中的‐实体反转义为-; - 自定义实体
&userdefined;被错误转成&userdefined;,需保留原实体格式。
解决方案
使用XSLT3.0的xsl:analyze-string精准匹配目标实体,避免误处理原生字符和自定义实体:
核心XSLT代码
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 复制所有节点结构,仅处理属性和文本内容 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理属性中的实体引用 --> <xsl:template match="@*"> <xsl:attribute name="{name()}"> <xsl:analyze-string select="." regex="&(userdefined|hyphen);"> <xsl:matching-substring> <xsl:choose> <!-- 保留自定义实体&userdefined; --> <xsl:when test="regex-group(1) = 'userdefined'"> <xsl:text>&userdefined;</xsl:text> </xsl:when> <!-- 将‐反转义为'-' --> <xsl:when test="regex-group(1) = 'hyphen'"> <xsl:text>-</xsl:text> </xsl:when> </xsl:choose> </xsl:matching-substring> <!-- 保留原生字符和其他未匹配内容 --> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:attribute> </xsl:template> <!-- 处理文本节点中的实体引用 --> <xsl:template match="text()"> <xsl:analyze-string select="." regex="&(userdefined|hyphen);"> <xsl:matching-substring> <xsl:choose> <xsl:when test="regex-group(1) = 'userdefined'"> <xsl:text>&userdefined;</xsl:text> </xsl:when> <xsl:when test="regex-group(1) = 'hyphen'"> <xsl:text>-</xsl:text> </xsl:when> </xsl:choose> </xsl:matching-substring> <xsl:non-matching-substring> <xsl:value-of select="."/> </xsl:non-matching-substring> </xsl:analyze-string> </xsl:template> </xsl:stylesheet>
代码说明
- 默认模板:复制所有XML节点和属性结构,确保输出与输入的XML结构一致;
- 属性处理:针对属性值中的实体,精准匹配
&userdefined;和‐,分别保留自定义实体、反转义‐为-,原生-字符直接保留; - 文本处理:逻辑与属性处理一致,确保文本内容中的实体处理符合需求。
测试效果
- 输入XML:
<name id="123-24">abc&hyphen;pqr &userdefined;</name>
- 输出XML:
<name id="123-24">abc-pqr &userdefined;</name>
完全符合需求:原生-保持不变,‐被反转义为-,自定义实体&userdefined;原样保留。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

