#sql #xslt #plsql #transform #oracle11gr2
#sql #xslt #plsql #преобразование #oracle11gr2
Вопрос:
Поскольку мы переместили базу данных с 11.2.0.2.0 на 11.2.0.4.0, xmltype.transform
функция получила специфическое поведение.
Проблема в том, что раньше он не работал нормально: он заменил все теги на версию open-close (например, он заменил <br />
на <br></br>
), но я мог с этим смириться. Теперь он ведет себя наоборот (заменяет все одним тегом), и это создает большую проблему с <script></script>
тегом, потому что этот тег должен быть явно закрыт с помощью a </script>
, иначе браузер думает, что он не закрыт, даже если он закрыт, поэтому <script />
=> все веб-страницы теперь повреждены.
Пример:
declare
xml xmltype := new xmltype('<?xml version="1.0" encoding="ISO-8859-1"?><document></document>');
xsl xmltype := new xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
</head>
<body>
<br />
</body>
</html>
</xsl:template>
</xsl:stylesheet>');
begin
dbms_output.put_line(xml.transform(xsl,null).getclobval());
end;
В версии 11.2.0.2.0 это работает следующим образом:
<html><head><script src="jquery-1.11.1.min.js"></script></head><body><br></br></body></html>
В 11.2.0.4.0 это работает по-другому:
<html>
<head>
<script type="text/javascript" src="jquery-1.11.1.min.js"/>
</head>
<body>
<br/>
</body>
</html>
Я предполагаю, что проблема в форматировании, но я не настроил ничего другого, чтобы включить его…
Что интересно, я нашел эту статью с другой проблемой, но с тем же обходным путем в качестве решения:
select xmltransform(xmltype('<?xml version="1.0" encoding="ISO-8859-1"?><document></document>'),
xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<script src="jquery-1.11.1.min.js"></script>
</head>
<body>
<br />
</body>
</html>
</xsl:template>
</xsl:stylesheet>')) html
from dual
это просто работает в каждой версии и дает правильный результат (тот, который удвоен <br />
, но, как я уже сказал, для меня это не имеет значения).
В документации Oracle ничего не сказано о различии в этих функциях; они даже много раз говорят, что это одни и те же функции (см. Здесь ).
Я, конечно, воспользуюсь этим обходным путем, но, пожалуйста, скажите мне: возможно ли заставить его снова работать без изменения кода?
В чем причина такого поведения?
Заранее благодарю вас.
Комментарии:
1. Извините за, возможно, раздражающий вопрос, но … Разве
<xsl:template-match>
узел не должен содержать такие вещи, какamp;<htmlamp;>
,amp;<script src=amp;quot;...amp;quot;amp;>
, … вместо<html>
,<script src="...">
, … ? Я подозреваю, что причиной ваших проблем является содержимое шаблона XSL, а не измененное поведение механизма преобразования XSL.2.
amp;<htmlamp;>
будет отображаться в браузере как строка<html>
, а не интерпретироваться как тег. Это абсолютно неверно. Вы видели какой-нибудь пример, где ваша идея вообще работает? Смотрите пример w3c , они имеют точно такую же структуру. И если ваша идея верна, почему мой XSLT работал раньше и почему он работает только с другой функцией?3. Извините, Саймон, я понятия не имею, почему это работало раньше и не работает сейчас. Извините, если я вас чем-то расстроил. Я просто «думал вслух»… Я вижу, что вы отправляете свой XSLT в виде строки в конструктор xmltype(), который явно анализирует также содержимое узла <xsl:template> как другие XML-узлы. Вот почему я предположил, что вы, по крайней мере, попытались выполнить html-экранирование содержимого <xsl:template> . Если бы я был абсолютно уверен, что я прав, я бы написал обычный ответ на ваш вопрос. Но я совсем не уверен, я просто опубликовал идею в качестве комментария.
4. Да, никаких проблем. Извините за немного грубые слова…
5. Оба сценария отлично работают в версии 11.2.0.3.0. вероятно, это вам не очень поможет, но может сузить его до чего-то, что происходит между .3 и .4…