Неожиданные экранированные CR, вставленные с преобразованием XSLT output-method = "text" - PullRequest
0 голосов
/ 21 апреля 2019

Мой вопрос здесь заключается в том, какова может быть логика следующего поведения или, если это ошибка (в MSXML6 под Windows), и даже в том, что сбой логики может послужить причиной такой ошибки.

Рассмотрим входной файл 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 ] Ниже приведен минимальный код JScript для дублированияпроблема.
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.xml и test.xslt соответственно, преобразование в командной строке cmd можно запустить как ,,,

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

C:\etc>

1 Ответ

1 голос
/ 21 апреля 2019

Я думаю, что это ошибка MSXML 6 и «нового парсера», который вы включаете с помощью xslDoc.setProperty("NewParser", true);.Даже не используя XSLT вообще, вы можете загрузить документ, например

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

, с помощью MSXML 6 и «нового анализатора» и проверить свойство 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;.

...