Chromium内核浏览器DOMParser与XMLSerializer嵌套CDATA往返失效问题
Chromium内核浏览器DOMParser处理嵌套CDATA往返异常的解决方案
问题背景
当使用包含正确嵌套CDATA结构的XML字符串(其中嵌套CDATA的结束标记]]被编码为]]]]><![CDATA[),执行以下XML往返操作时:
var parser = new DOMParser(); var resultDocument = parser.parseFromString(sourceXMLString, 'text/xml'); var serializer = new XMLSerializer(); var resultXMLString = serializer.serializeToString(resultDocument);
Chromium内核的Edge/Chrome浏览器会生成错误的XML字符串:原有的]]]]><![CDATA[编码被替换为]],丢失了正确的嵌套CDATA编码;同时parser.parseFromString返回的DOM文档已损坏,导致XSL转换运行失败。而Firefox和Safari的往返结果与原字符串完全一致。
疑问:是否可以控制Chromium版本DOMParser的parseFromString方法行为,以得到正确的往返结果?
可复现测试代码
以下HTML代码可在不同浏览器中运行对比:
<html> <body> <p id="demo"></p> <script> const simpleXML = "<root><element>Element Data</element></root>"; const cdataXML = "<root><htmlDef><![CDATA[<html><body><div></div></body></html>]]></htmlDef></root>"; const embeddedCDATAXML = "<root><htmlDefn><![CDATA[<div><![CDATA[ Just Rubbish Data $#$^#^$ ]]]]><![CDATA[></div><div></div>]]></htmlDefn></root>"; function testRoundTrip(sourceXMLString) { var parser = new DOMParser(); var resultDocument = parser.parseFromString(sourceXMLString, 'text/xml'); var serializer = new XMLSerializer(); var resultXMLString = serializer.serializeToString(resultDocument); if (sourceXMLString === resultXMLString) { window.alert("XML字符串往返DOM完全匹配"); window.alert("原字符串 : " + sourceXMLString); } else { window.alert("XML字符串往返DOM不匹配"); window.alert("原字符串 : " + sourceXMLString); window.alert("结果字符串 : " + resultXMLString); } } </script> <h1>测试XML解析往返兼容性(不同浏览器)</h1> <h2>使用浏览器内置DOMParser()和XMLSerializer()</h2> <button type="button" onclick="testRoundTrip(simpleXML)">简单XML</button> <button type="button" onclick="testRoundTrip(cdataXML)">含CDATA的XML</button> <button type="button" onclick="testRoundTrip(embeddedCDATAXML)">含嵌套CDATA的XML</button> </body> </html>
解决方案
目前无法直接控制Chromium内核DOMParser的parseFromString方法行为来保留原始的CDATA编码格式,这是因为Chromium的XML解析实现会将CDATA节点的内容合并为纯文本,序列化时只会根据内容是否包含]]>来决定是否拆分CDATA,不会保留原始的编码拆分方式。
要解决这个问题,可以采取以下两种方案:
- 自定义XML序列化逻辑:解析DOM后,手动遍历CDATA节点,检查内容中是否存在
]],如果存在则按照原始的编码方式拆分CDATA段进行序列化,而非依赖XMLSerializer。 - 替换嵌套CDATA的编码方式:改用实体编码替代CDATA嵌套,比如将
]]替换为]]>(需确保XML解析器能正确处理实体),或者将需要嵌套的内容放在单独的元素节点中,而非CDATA内部。
该问题属于Chromium内核的已知兼容性问题,目前暂无官方参数或配置可调整DOMParser的这种行为。
内容的提问来源于stack exchange,提问作者Garry P
相关产品推荐
相关产品推荐

