2017-02-08 18 views
1

У меня есть XML, как это,XSLT - преобразование символов Юникода

<doc> 
    <?PIValue &#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;?> 
    <p>&#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;</p> 
</doc> 

У меня есть XSLT преобразование для этого XML следующим образом,

<xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="doc"> 
     <doc> 
      <xsl:apply-templates/> 
      <p2><xsl:value-of select="processing-instruction('PIValue')"/></p2> 
     </doc> 
    </xsl:template> 

    <xsl:template match="p"> 
     <p1> 
      <xsl:apply-templates/> 
     </p1> 
    </xsl:template> 

Выход из выше преобразования это это,

<doc> 
    <?PIValue &#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;?> 
    <p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1> 
    <p2>&amp;#x00D2;&amp;#x00D3;&amp;#x00D4;&amp;#x00D5;&amp;#x00D6;&amp;#x00D8; &amp;#x00C0;&amp;#x00C1;&amp;#x00C2;&amp;#x00C3;&amp;#x00C4;&amp;#x00C5;</p2> 
</doc> 

Как вы можете видеть символы Юникода находились в пределах <p>, элемент отображался как обычный текст на выходе (в пределах <p1> элемент). Но те же символы юникода в инструкции обработки не показаны, как соответствующие символы на выходе (в пределах <p2>).

Как я могу изменить свое преобразование, чтобы показать текстовую строку и в элементе.

expected output, 

<doc> 
    <?PIValue &#x00D2;&#x00D3;&#x00D4;&#x00D5;&#x00D6;&#x00D8; &#x00C0;&#x00C1;&#x00C2;&#x00C3;&#x00C4;&#x00C5;?> 
    <p1>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p1> 
    <p2>ÒÓÔÕÖØ ÀÁÂÃÄÅ</p2> 
</doc> 
+0

Хороший вопрос, но нет простого решения, так как с элементом 'p' во вводе символьные ссылки в содержимом просто преобразуются парсером XML в соответствующие символы. Это не происходит с содержимым pi, так как это содержание символа. Какой процессор XSLT вы используете точно? –

+0

@MartinHonnen, я использую XSLT 2.0 – sanjay

ответ

2

В XML, ссылки на символы (например, &#xd2;) признается в элементах и ​​атрибуты контента, но не в инструкции по обработке или комментарии. Поэтому в вашей инструкции обработки строка &#x00D2; представляет собой всего лишь строку из 8 символов, а не ссылку на единственный символ xD2.

Если вы хотите интерпретировать строки &#x00D2; как ссылки на символы, то вы можете отправить их в синтаксический анализатор XML (как предполагает Мартин Хоннен), или вы можете разобрать их «вручную» в своем собственном коде. Это не так сложно: xsl:analyze-string будет извлекать часть '00D2', писать рекурсивную функцию для преобразования hex в integer довольно просто, а затем финальная часть - вызвать codepoints-to-string для преобразования целочисленного кода в символ (= строка длины один).

0

Если вы можете переключиться на XSLT 3.0 вы можете использовать

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"> 


    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="doc"> 
     <doc> 
      <xsl:apply-templates/> 
      <p2><xsl:value-of select="parse-xml-fragment(processing-instruction('PIValue'))"/></p2> 
     </doc> 
    </xsl:template> 

    <xsl:template match="p"> 
     <p1> 
      <xsl:apply-templates/> 
     </p1> 
    </xsl:template> 
</xsl:transform> 
+0

Спасибо за ответ. но я хочу сделать это в XSLT 2.0. Нет ли в XSLT 2.0 прямого метода для этого? – sanjay