О зарезервированных символах JAXP, XSLT и XML

Похоже, JAXP позволяет присвоить узлу документа любое значение, включая ‹,>, & и другие. Игра с зарезервированными символами XML и XSLT вызывает вопрос. Рассмотрим следующий код:

DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();

...

Element field = doc.createElement("col");
field.setTextContent( "<p>&]]" );
row.appendChild( field );

...

TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("templateName.xsl"));
Transformer transformer = factory.newTransformer(xslt);

transformer.transform( new DOMSource(doc), new StreamResult(printer) );

Теперь, если у нас есть

<xsl:value-of select="col" disable-output-escaping="yes"/>

в "templateName.xsl" результат будет выглядеть так:

"<p>&]]"

и если у нас есть это

<xsl:value-of select="col"/>

вывод будет

&lt;p&gt;&amp;]]

поэтому в основном мой вопрос заключается в том, какое внутреннее представление данных использует JAXP, чтобы это

"<p>&]]"

в порядке? Это не может быть ни текстовый узел, ни узел CDATA. Что это? Я считаю, что для преобразования должен быть предоставлен действующий XML-документ. С другой стороны, атрибут disable-output-escaping указывает, что специальные символы должны выводиться как есть, означает ли это, что наш узел "col" сохраняется, как в коде? Почему тогда XML-документ действителен?


person user3234859    schedule 22.05.2014    source источник


Ответы (2)


disable-output-escaping обычно работает только в том случае, если вывод преобразования записывается прямо в сериализатор. Хотя спецификация XSLT описывает это в терминах расширения модели данных, где с каждым символом в текстовом узле связан дополнительный бит, говорящий «отключить экранирование этого символа», большинство реализаций вряд ли позволят вам сохранить экземпляр эта модель представляет собой дерево в памяти, и дополнительный бит существует только тогда, когда деревья передаются потоком от преобразователя к сериализатору.

(В реализации Saxon вместо использования дополнительного бита на символ он вставляет символ x00 в поток данных, передаваемый от преобразователя к сериализатору, чтобы включить или выключить экранирование; это зависит от того факта, что x00 является допустимым символом в Java. но не в XML).

person Michael Kay    schedule 22.05.2014

Хорошо, думаю, я понял, как это работает. Любые зарезервированные символы XML должны быть экранированы, если они не находятся в узле CDATA. Далее, что будет делать атрибут disable-output-escaping = "yes", зависит от типа узла. Если это текстовый узел, он отменяет экранирование, так что "" преобразуется в "‹ ". Если это узел CDATA, он отключит экранирование, и CDATA будет выводиться как есть. В любом случае все теги, заключенные в текстовый узел, удаляются, а сохраняются для CDATA (и экранируются в соответствии с параметром disable-output-escaping). Таким образом, либо DOMSource, либо Transformer (не уверен, кто отображает DOM в XML) будут выполнять фактическое экранирование текстового узла DOM перед преобразованием (и CDATA остается нетронутым). Итак, для текстового узла disable-output-escaping следует читать undo-xml-escaping, что решает мою путаницу.

В любом случае, спасибо Майклу за объяснение!

person user3234859    schedule 23.05.2014