使用XSLT output-method =“text”转换插入的意外转义CR

问题描述 投票:0回答:1

我的问题是以下行为的逻辑可能是什么,或者它是否是一个错误(在Windows下的MSXML6中)甚至逻辑的失败可能会支撑这样的错误。

考虑输入XML文件。

<?xml version="1.0" encoding="utf-8"?>
<root>
    <item>first item</item>
    <item>second item</item>
</root>

以下XSLT尝试使用标准Windows CR-LF行结尾以文本格式(每行一个)提取项目。

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE xsl:stylesheet [<!ENTITY eol "<![CDATA[&#xD;&#xA;]]>">]> <!-- (a) !?? -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" version="1.0" encoding="utf-8" media-type="text/plain"/>
<xsl:strip-space elements='*'/>
<xsl:template match="item"> <!-- list items, one per line -->
    <xsl:value-of select="."/>
    <xsl:text disable-output-escaping="yes">&eol;</xsl:text>
</xsl:template>
</xsl:stylesheet>

但是,我得到的输出包括无关的转义CR,在每行的末尾输出为"&#13;"

first item&#13;
second item&#13;

同样的问题是关于上面的特定行为,我觉得很奇怪。我特别没有要求替代方案或变通方法,事实上其变体看起来工作得很好。

<!DOCTYPE xsl:stylesheet [<!ENTITY eol "<![CDATA[&#xA;]]>">]> <!-- (b) works  -->
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&amp;#xA;">]>         <!-- (c) no newlines in output -->
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&#x26;#xA;">]>        <!-- (d) works  -->
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&#xA;">]>             <!-- (e) no newlines in output -->
<!DOCTYPE xsl:stylesheet [<!ENTITY eol "&#xD;&#xA;">]>        <!-- (f) works  -->


[ EDIT ] Following is the minimal JScript code to duplicate the issue.
var vArgs = WScript.Arguments;
var xmlFile = vArgs(0);
var xslFile = vArgs(1);

var xmlDOMDocProgID = "MSXML2.DOMDocument.6.0";

var xmlDoc = new ActiveXObject(xmlDOMDocProgID);
xmlDoc.setProperty("NewParser", true);
xmlDoc.validateOnParse = false;
xmlDoc.async = false;
xmlDoc.load(xmlFile);

var xslDoc = new ActiveXObject(xmlDOMDocProgID);
xslDoc.setProperty("NewParser", true);
xslDoc.setProperty("ProhibitDTD", false);
xslDoc.validateOnParse = false;
xslDoc.async = false;
xslDoc.load(xslFile);

WScript.StdOut.Write(xmlDoc.transformNode(xslDoc));

假设它保存为test.js并且xml / xslt文件分别是test.xmltest.xslt,cmd提示符下的转换可以作为,,,运行

C:\etc>cscript //nologo test.js test.xml test.xslt
first item&#13;
second item&#13;

C:\etc>
xml xslt msxml msxml6
1个回答
1
投票

我认为这是MSXML 6的一个错误,你使用xslDoc.setProperty("NewParser", true);启用了“新解析器”。即使不使用任何XSLT,您也可以加载文档

<!DOCTYPE root [<!ENTITY eol "<![CDATA[&#xD;&#xA;]]>">]>
<root>&eol;</root>

使用MSXML 6和“new parser”并检查root / document元素的text属性

var xmlDOMDocProgID = "MSXML2.DOMDocument.6.0";

var xmlDoc = new ActiveXObject(xmlDOMDocProgID);
xmlDoc.setProperty("NewParser", true);
xmlDoc.setProperty("ProhibitDTD", false);
xmlDoc.validateOnParse = false;
xmlDoc.load('cdata-input2.xml');

WScript.Echo(xmlDoc.documentElement.text);

它显示了&#13;

如果你也输出WScript.Echo(xmlDoc.documentElement.firstChild.firstChild.nodeValue);你会得到相同的值,所以实体解析最终会将<!ENTITY eol "<![CDATA[&#xD;&#xA;]]>">从DTD子集和&eol;“转换”为一个实体引用节点,其中包含一个节点值的CDATA节点,其中转义的十六进制字符引用&#xD;现在是一个转义十进制的&#13;

© www.soinside.com 2019 - 2024. All rights reserved.