You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何替换XSLT中CDATA转义字符会导致输出异常?

问题描述

我肯定忽略了一些基础内容,还请见谅。

原始XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:template match="/">
        <GenericDataSet>
            <StatementName>
                <Header action="INSERT">
                    <table>XML</table>
                    <access>
                        <XML_DATA><xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
      <xsl:copy-of select="*"/>    
      <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text></XML_DATA>
                    </access>
                </Header>
            </StatementName>
        </GenericDataSet>
    </xsl:template>
</xsl:stylesheet>

预期输出(符合预期的结果)

<GenericDataSet>
   <StatementName>
      <Header action="INSERT">
         <table>XML</table>
         <access>
            <XML_DATA><![CDATA[<note>
                  <to>Tove</to>
                  <from>Jani</from>
                  <heading>Reminder</heading>
                  <body>Don't forget me this weekend!</body>
               </note>]]></XML_DATA>
         </access>
      </Header>
   </StatementName>
</GenericDataSet>

修改后的XSLT代码(替换转义字符后)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:template match="/">
        <GenericDataSet>
            <StatementName>
                <Header action="INSERT">
                    <table>XML</table>
                    <access>
                        <XML_DATA><xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
      <xsl:copy-of select="*"/>    
      <xsl:text disable-output-escaping="yes">]]></xsl:text></XML_DATA>
                    </access>
                </Header>
            </StatementName>
        </GenericDataSet>
    </xsl:template>
</xsl:stylesheet>

异常输出

<GenericDataSet>
   <StatementName>
      <Header action="INSERT">
         <table>XML</table>
         <access>
            <XML_DATA></xsl:text>
      <xsl:copy-of select="*"/>    
      <xsl:text disable-output-escaping="yes"></XML_DATA>
         </access>
      </Header>
   </StatementName>
</GenericDataSet>

请问出现这种情况的原因是什么?我尝试过不同版本的XSLT映射,替换转义字符都会导致结果不同。


原因分析

核心问题在于XSLT本身是XML格式的文档,必须严格遵守XML的语法规则:

  • 在XML的文本内容里,<和>属于特殊字符,不能直接出现,必须转义成&lt;和&gt;,否则XML解析器会把它们误认为是XML标签的起始/结束标记。
  • 当你把&lt;![CDATA[改成<![CDATA[时,XML解析器会把<![CDATA[当成一个新的XML标签的开始,而不是<xsl:text>元素的文本内容。这直接破坏了XSLT文档的结构:解析器会认为<xsl:text>元素在<![CDATA[之前就结束了,后续的]]></xsl:text>也会被拆解成无效的标签片段,最终导致输出混乱。
  • 而转义后的&lt;和&gt;会被XML解析器正确识别为文本内容,在XSLT执行时,通过disable-output-escaping="yes"设置,这些转义字符会被还原成<和>,最终输出正确的CDATA包裹结构。

内容的提问来源于stack exchange,提问作者Integration_Consultant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:07:15