使用Saxon HE 11.4时<xsl:copy-of>未保留XML标签的原因排查
问题原因
你的问题根源在于设置了<xsl:output method="text"/>(以及xsl:result-document中的相同配置)。当使用文本输出模式时,XSLT处理器会将所有XML元素视为"透明"对象——仅输出元素内的文本内容,完全丢弃元素标签本身。哪怕使用xsl:copy-of也无法保留标签,因为文本输出模式会忽略所有标记结构。
解决方案
方案1:使用XSLT 3.0的serialize()函数(适配Saxon HE 11.4)
Saxon HE 11.4支持XSLT 3.0,你可以通过serialize()函数直接将元素序列化为带标签的文本字符串:
- 将样式表版本改为3.0:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - 替换原有的
xsl:copy-of代码:<!-- 替换前 --> <xsl:copy-of select="node()"/> <!-- 替换后 --> <xsl:value-of select="serialize(.)"/>
方案2:自定义递归模板(兼容XSLT 2.0)
如果需要坚持使用XSLT 2.0,可编写递归模板手动生成标签文本:
- 添加以下模板:
<xsl:template name="element-to-text"> <xsl:param name="element"/> <!-- 输出开始标签 --> <xsl:text><</xsl:text> <xsl:value-of select="local-name($element)"/> <xsl:text>></xsl:text> <!-- 输出元素内容 --> <xsl:apply-templates select="$element/node()" mode="element-to-text"/> <!-- 输出结束标签 --> <xsl:text></</xsl:text> <xsl:value-of select="local-name($element)"/> <xsl:text>></xsl:text> </xsl:template> <xsl:template match="text()" mode="element-to-text"> <xsl:value-of select="."/> </xsl:template> - 调用模板替换
xsl:copy-of:<xsl:call-template name="element-to-text"> <xsl:with-param name="element" select="."/> </xsl:call-template>
额外优化
你当前代码中xsl:result-document内部的<root>元素在文本输出模式下完全无效,可以直接删除以简化代码。
内容的提问来源于stack exchange,提问作者xinatanil
相关产品推荐
相关产品推荐

