Экранирование значений атрибутов в JDOM 2 с отключенным выходным экранированием набора PI

Я нахожусь в инкубационной команде Apache JSPWiki и пытаюсь обновить наш проект с JDOM 1.1.2 до JDOM 2.0.5. Кажется, что 98% преобразования работают нормально, но я столкнулся с одной проблемой, которая мешает нам выполнить обновление, связанное с JDOM2 XMLOutputter.outputElementContent(). А именно, мы всегда добавляем инструкцию обработки, чтобы отключить экранирование вывода, но мы по-прежнему ожидаем, что амперсанды и кавычки внутри атрибутов будут экранированы в и . JDOM1 обрабатывает этот PI так, как мы хотим, но JDOM2 интерпретирует эту инструкцию, чтобы также отключить экранирование вывода в пределах значений атрибутов. Я не уверен, является ли это ошибкой/функцией в JDOM2 или JSPWiki неправильно полагается на ошибку/функцию в JDOM1. [1] показывает, как мы настраиваем элемент Format в JSPWiki перед вызовом outputElementContent().

Например, в JDOM1:

<a href="http://www.google.com/?p=a&c=d">Hello</a>

отображается как:

<a href="http://www.google.com/?p=a&amp;c=d">Hello</a> (good, ampersand is escaped)

Это связано с тем, что в JDOM1 XMLOutputter.printAttibutes()[2] экранирует значения атрибутов независимо от инструкции обработки.

но в JDOM2 мы получаем:

<a href="http://www.google.com/?p=a&c=d">Hello</a>  (bad, still an ampersand character)

... потому что в JDOM2 атрибут AbstractXMLOutputProcessorEscapedEntitiesFilter[3] будет выполнять экранирование только в том случае, если "getEscapeOutput()" имеет значение true, но для getEscapeOutput автоматически устанавливается значение false[4], если установлено PI отключения выхода-экранирования.

Если мы вызовем Format.setIgnoreTrAXEscapingPIs() (или просто не добавим для начала PI с отключенным выводом-экранированием), мы в конечном итоге столкнемся с противоположной проблемой экранирования тега.

Может ли кто-нибудь придумать хорошее/простое решение для нас?

Спасибо, Глен

[1] http://svn.apache.org/viewvc/incubator/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/render/XHTMLRenderer.java?revision=1486481&view=markup#l56

[2] http://grepcode.com/file/repo1.maven.org/maven2/org.jdom/jdom/1.1/org/jdom/output/XMLOutputter.java#1132

[3] http://grepcode.com/file/repo1.maven.org/maven2/org.jdom/jdom2/2.0.4/org/jdom2/output/support/AbstractXMLOutputProcessor.java#392

[4] http://grepcode.com/file/repo1.maven.org/maven2/org.jdom/jdom2/2.0.4/org/jdom2/output/support/AbstractXMLOutputProcessor.java#665


person Glen Mazza    schedule 03.07.2013    source источник
comment
Привет, Глен. Я думаю об этом.... просто чтобы вы знали. Моя интуиция подсказывает, что JDOM 2.x работает правильно... Должно быть относительно легко протестировать использование другого движка, отличного от JDOM.... но кто сказал, что другой движок делает это правильно. Я считаю, что значение атрибута должно обрабатываться так же, как текстовое содержимое (что и делает JDOM 2.x). Это не то, для чего у меня есть тестовые примеры на стороне JDOM 1.x, поэтому у меня нет прецедента в JDOM 1.x, которому можно было бы следовать. В общем, я очень тщательно поддерживаю функциональную совместимость между 1.x и 2.x. Загляну в него.   -  person rolfl    schedule 03.07.2013
comment
Что ж, казалось, что значения атрибутов обрабатываются не только как текстовое содержимое, но и как элементы, т. е. по принципу «все или ничего» (но я мог легко неправильно прочитать код). Если у меня есть тег привязки HTML, я может захотеть сохранить фигурные скобки вокруг привязок (не экранировать их), но в то же время убедиться, что любые амперсанды в значениях атрибутов и текстовом содержимом по-прежнему экранированы. Предоставляет ли JDOM2 эту возможность? (Кстати, спасибо за быстрый ответ.)   -  person Glen Mazza    schedule 03.07.2013


Ответы (1)


Я придумал простое решение:

Я создал подкласс AbstractXMLOutputProcessor с переопределением attributeEscapedEntitiesFilter(), чтобы больше не отключалась проверка экранирования вывода: http://svn.apache.org/viewvc/incubator/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/render/CustomXMLOutputProcessor.java?revision=1499446&view=markup

...и затем связал его с XMLOutputter (строка 62): http://svn.apache.org/viewvc/incubator/jspwiki/trunk/jspwiki-war/src/main/java/org/apache/wiki/render/XHTMLRenderer.java?revision=1499446&view=markup#l62

Теперь работает нормально.

person Glen Mazza    schedule 03.07.2013
comment
Отлично, я рад, что вам было легко переопределить класс так, как вы хотели. Для меня это подтверждение того, что API был настроен «правильно». Я искал какую-то спецификацию для побега PI, и не нашел. Я не знаю, какой правильный ответ. Это ваше исправление будет хорошо работать для вас. Если вы часто выполняете вывод, вы можете захотеть сделать пользовательский класс статическим конечным экземпляром.... может лучше скомпилироваться (JIT). - person rolfl; 03.07.2013