, , , ,

Неправильно формированный тэг br при выполнении xmltransform (wrong br after xmltransform)

суббота, 27 марта 2010 г. 0 коммент.

Под 11 версией базы неожиданно перестал правильно работать xmltransform.

В соответсвии с W3C рекомендациями элементы написанные как
<br/> или <br></br> должны быть трансформированы в <br>, но этого не происходит.

Рассмотрим на примере. XML для трансформации:


<?xml version="1.0" encoding="Windows-1251"?>
<REQUEST xmlns="http://localhost/schemas/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DATA>
<ID>12345</ID>
<ID_PARENT>1234</ID_PARENT>
<NAME>Узел 12345</NAME>
<FULL_NAME>Узел 12345, родитель 1234</FULL_NAME>
</DATA>
</REQUEST>

XSLT для трансформации:


<?xml version="1.0" encoding="Windows-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdt="http://localhost/schemas/data" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Элемент дерева</title>
</head>
<body>
ИД: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID"/></b>< br></br>
ИД родителя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID_PARENT"/></b>< br/>
Имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:NAME"/></b>< br> </br>
Полное имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:FULL_NAME"/></b>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Выполним трансформацию в Oracle DB 10g и 11g. Сначала в Oracle DB 11g


SQL> set long 32000
SQL> select * from v$version where rownum=1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production

SQL>
SQL> select xmltransform(xmltype(
2 '<?xml version="1.0" encoding="Windows-1251"?>
3 <REQUEST xmlns="http://localhost/schemas/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4 <DATA>
5 <ID>12345</ID>
6 <ID_PARENT>1234</ID_PARENT>
7 <NAME>Узел 12345</NAME>
8 <FULL_NAME>Узел 12345, родитель 1234</FULL_NAME>
9 </DATA>
10 </REQUEST>'), xmltype(
11 '<?xml version="1.0" encoding="Windows-1251"?>
12 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
13 xmlns:sdt="http://localhost/schemas/data" version="1.0">
14 <xsl:output method="html"/>
15 <xsl:template match="/">
16 <html>
17 <head>
18 <title>Элемент дерева</title>
19 </head>
20 <body>
21 ИД: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID"/></b>< br></br>
22 ИД родителя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID_PARENT"/></b>< br/>
23 Имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:NAME"/></b>< br> </br>
24 Полное имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:FULL_NAME"/></b>
25 </body>
26 </html>
27 </xsl:template>
28 </xsl:stylesheet>')).getclobval()
29 from dual;

XMLTRANSFORM(XMLTYPE('<?XMLVER
--------------------------------------------------------------------------------
<html><head><title>Элемент дерева</title></head><body>
ИД: <b>12345</b>< br></br>
ИД родителя: <b>1234</b>< br></br>
Имя: <b>Узел 12345</b>< br></br>
Полное имя: <b>Узел 12345, родитель 1234</b></body></html>

SQL>

Теперь в Oracle DB 10g


SQL> set long 32000
SQL> select * from v$version where rownum=1;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod

SQL>
SQL> select xmltransform(xmltype(
2 '<?xml version="1.0" encoding="Windows-1251"?>
3 <REQUEST xmlns="http://localhost/schemas/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4 <DATA>
5 <ID>12345</ID>
6 <ID_PARENT>1234</ID_PARENT>
7 <NAME>Узел 12345</NAME>
8 <FULL_NAME>Узел 12345, родитель 1234</FULL_NAME>
9 </DATA>
10 </REQUEST>'), xmltype(
11 '<?xml version="1.0" encoding="Windows-1251"?>
12 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
13 xmlns:sdt="http://localhost/schemas/data" version="1.0">
14 <xsl:output method="html"/>
15 <xsl:template match="/">
16 <html>
17 <head>
18 <title>Элемент дерева</title>
19 </head>
20 <body>
21 ИД: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID"/></b>< br></br>
22 ИД родителя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID_PARENT"/></b>< br/>
23 Имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:NAME"/></b>< br> </br>
24 Полное имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:FULL_NAME"/></b>
25 </body>
26 </html>
27 </xsl:template>
28 </xsl:stylesheet>')).getclobval()
29 from dual;


XMLTRANSFORM(XMLTYPE('<?XMLVER
--------------------------------------------------------------------------------
<html><head><title>Элемент дерева</title></head><body>
ИД: <b>12345</b>< br/>
ИД родителя: <b>1234</b>< br/>
Имя: <b>Узел 12345</b>< br/>
Полное имя: <b>Узел 12345, родитель 1234</b></body></html>

SQL>

И хотя в 10.2 тоже неправильно формируется тэг br, вместо <br /> мы видим <br/>, браузеры правильно отображают этот тэг.
А сочетание элемент <br /></br> интерпретируется браузерами, как два тега <br />.
Для того чтобы в Oracle DB 11g правильно выводились тэги <br />, их необходимо экранировать с помощью инстркции xsl:text.
Трансформация будет выглядеть следующим образом.


<?xml version="1.0" encoding="Windows-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdt="http://localhost/schemas/data" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>Элемент дерева</title>
</head>
<body>
ИД: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
ИД родителя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID_PARENT"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
Имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:NAME"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
Полное имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:FULL_NAME"/></b>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Смотрим результат:


SQL> set long 32000
SQL> select * from v$version where rownum=1;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production

SQL>
SQL> select xmltransform(xmltype(
2 '<?xml version="1.0" encoding="Windows-1251"?>
3 <REQUEST xmlns="http://localhost/schemas/data" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4 <DATA>
5 <ID>12345</ID>
6 <ID_PARENT>1234</ID_PARENT>
7 <NAME>Узел 12345</NAME>
8 <FULL_NAME>Узел 12345, родитель 1234</FULL_NAME>
9 </DATA>
10 </REQUEST>'), xmltype(
11 '<?xml version="1.0" encoding="Windows-1251"?>
12 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sdt="http://localhost/schemas/data" version="1.0">
13 <xsl:output method="html"/>
14 <xsl:template match="/">
15 <html>
16 <head>
17 <title>Элемент дерева</title>
18 </head>
19 <body>
20 ИД: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
21 ИД родителя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:ID_PARENT"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
22 Имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:NAME"/></b><xsl:text disable-output-escaping="yes"><![CDATA[< br>]]></xsl:text>
23 Полное имя: <b><xsl:value-of select="/sdt:REQUEST/sdt:DATA/sdt:FULL_NAME"/></b>
24 </body>
25 </html>
26 </xsl:template>
27 </xsl:stylesheet>')).getclobval()
28 from dual;

XMLTRANSFORM(XMLTYPE('<?XMLVER
--------------------------------------------------------------------------------
<html><head><title>Элемент дерева</title></head><body>
ИД: <b>12345</b>< br>
ИД родителя: <b>1234</b>< br>
Имя: <b>Узел 12345</b>< br>
Полное имя: <b>Узел 12345, родитель 1234</b></body></html>

SQL>

Теперь все правильно.


Читать полностью