XSLT转换中XML标签丢失与实体转义异常问题咨询
解决方案
一、保留XML标签
你的XSL中已使用<xsl:mode on-no-match="shallow-copy"/>,理论上应复制所有XML元素标签。若出现标签丢失,先排查两点:
- 输入XML格式是否合法(比如示例中的
<name>abc<name>是未闭合的错误标签,正确写法为<name>abc</name>) - 确认所用Saxon版本支持XSLT 3.0的
shallow-copy模式(你使用的net.sf.saxon.TransformerFactoryImpl是Saxon实现,版本不低于9.8即可支持)
若确认输入合法但标签仍丢失,可替换shallow-copy为显式模板,确保覆盖所有节点:
<xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template>
二、保留实体不被转义
XML解析器会自动将实体(如'、§)解析为对应字符,XSLT处理的是字符而非实体字符串。要保留实体,需通过字符映射将字符映射回对应的实体引用:
修改后的XSL样式表
<xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> <!-- 输出设置:启用所有字符映射,保持XML格式 --> <xsl:output method="xml" omit-xml-declaration="no" use-character-maps="mdash amp apos sect"/> <!-- 十六进制实体—转成— --> <xsl:character-map name="mdash"> <xsl:output-character character="—" string="&mdash;"/> </xsl:character-map> <!-- 保持&字符不转义(对应输入中的&转成&) --> <xsl:character-map name="amp"> <xsl:output-character character="&" string="&"/> </xsl:character-map> <!-- 将'字符映射回&apos; --> <xsl:character-map name="apos"> <xsl:output-character character="'" string="&apos;"/> </xsl:character-map> <!-- 将§字符映射回&sect; --> <xsl:character-map name="sect"> <xsl:output-character character="§" string="&sect;"/> </xsl:character-map> <!-- 复制所有节点和属性 --> <xsl:mode on-no-match="shallow-copy"/> </xsl:stylesheet>
关键说明
- 每个字符映射项将实际字符(如
'、§)转换为对应的实体引用字符串(如&apos;、&sect;),输出时就会显示为'、§。 use-character-maps属性需包含所有定义的字符映射名称,确保所有规则生效。- 如需保留其他实体,按相同格式添加新的字符映射即可。
三、Java代码无需调整
你当前的Java代码使用Saxon的TransformerFactory实现,已支持XSLT 3.0的字符映射功能,只需确保输入XML文件格式合法即可。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

