Вставьте html-сущности в xslt - PullRequest
2 голосов
/ 27 июня 2010

У меня есть несколько XML, которые содержат шестнадцатеричные коды символов, например, это так:

<char hex="AB"/>

Теперь я хочу преобразовать XSLT для отображения в браузере:

<xsl:value-of select="concat('&amp;#x', /char/@hex, ';', '')"/>

Однако вывод в браузере &amp;#xAB;, а не как я ожидал &#xAB; поэтому браузер не отображает символ для этого кода (который будет «), а только литеральную строку &#xAB;

Как я могу заставить XSL не убегать от амперсанда?

Ответы [ 2 ]

1 голос
/ 27 июня 2010

Это может быть выполнено, если вы установите output method на text.

Это преобразование :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

 <xsl:template match="char">
  <xsl:value-of select="concat('&amp;#x', /char/@hex, ';', '')"/>
 </xsl:template>
</xsl:stylesheet>

При применении к предоставленному документу XML :

<char hex="AB"/>

дает желаемый результат :

&#xAB;

Конечно, с textВ методе вывода нужно создать отдельные символы начальных и конечных тегов (<xsl:copy>, <xsl:copy-of>, <xsl:element> и буквальные элементы результата не создают никаких тегов в этом методе вывода), но с некоторым терпением все возможно.

Можно также использовать DOE (Disable Output Escapeing), но эта «функция» не является обязательной в спецификации XSLT.и некоторые процессоры XSLT (включая, я думаю, тот, что используется FF) не поддерживают DOE.

Вероятно, лучшее решение (не использующее method="text") - это следующее :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my"
>
 <xsl:output omit-xml-declaration="yes" indent="yes" encoding="us-ascii"/>

 <my:hex>
  <code start="8">&#x80;&#x81;&#x82;&#x83;&#x84;&#x85;&#x86;&#x87;&#x88;&#x89;&#x8A;&#x8B;&#x8C;&#x8D;&#x8E;&#x8F;</code>
  <code start="9">&#x90;&#x91;&#x92;&#x93;&#x94;&#x95;&#x96;&#x97;&#x98;&#x99;&#x9A;&#x9B;&#x9C;&#x9D;&#x9E;&#x9F;</code>
  <code start="A">&#xA0;&#xA1;&#xA2;&#xA3;&#xA4;&#xA5;&#xA6;&#xA7;&#xA8;&#xA9;&#xAA;&#xAB;&#xAC;&#xAD;&#xAE;&#xAF;</code>
  <code start="B">&#xB0;&#xB1;&#xB2;&#xB3;&#xB4;&#xB5;&#xB6;&#xB7;&#xB8;&#xB9;&#xBA;&#xBB;&#xBC;&#xBD;&#xBE;&#xBF;</code>
  <code start="C">&#xC0;&#xC1;&#xC2;&#xC3;&#xC4;&#xC5;&#xC6;&#xC7;&#xC8;&#xC9;&#xCA;&#xCB;&#xCC;&#xCD;&#xCE;&#xCF;</code>
  <code start="D">&#xD0;&#xD1;&#xD2;&#xD3;&#xD4;&#xD5;&#xD6;&#xD7;&#xD8;&#xD9;&#xDA;&#xDB;&#xDC;&#xDD;&#xDE;&#xDF;</code>
  <code start="E">&#xE0;&#xE1;&#xE2;&#xE3;&#xE4;&#xE5;&#xE6;&#xE7;&#xE8;&#xE9;&#xEA;&#xEB;&#xEC;&#xED;&#xEE;&#xEF;</code>
  <code start="F">&#xF0;&#xF1;&#xF2;&#xF3;&#xF4;&#xF5;&#xF6;&#xF7;&#xF8;&#xF9;&#xFA;&#xFB;&#xFC;&#xFD;&#xFE;&#xFF;</code>
 </my:hex>

 <xsl:variable name="vHex" select="document('')/*/my:hex/*"/>

 <xsl:template match="char">
  <xsl:variable name="vchar1" select="substring(@hex,1,1)"/>
  <xsl:variable name="vchar2" select="substring(@hex,2,1)"/>

  <xsl:variable name="voffset">
   <xsl:choose>
     <xsl:when test="number($vchar2)">
        <xsl:value-of select="$vchar2"/>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="count($vHex[@start = $vchar2]/preceding-sibling::*)+9"/>
     </xsl:otherwise>
   </xsl:choose>
  </xsl:variable>

  <xsl:value-of select="substring($vHex[@start=$vchar1], $voffset, 1)"/>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному XML-документу :

<char hex="AB"/>

желаемый результат получается :

&#171;

Предполагается, что значения атрибута hex являются шестнадцатеричными в диапазоне от x80 до xFF.Если необходимо иметь значения в более широком диапазоне, например от x00 до XFF, к элементу my:hex

необходимо соответственно добавить больше элементов code.
0 голосов
/ 27 июня 2010

Я думаю, что ваша проблема больше, чем просто побег, но как насчет атрибута disable-output-escaping ?

<xsl:value-of disable-output-escaping="yes" select="concat('&amp;#x', /char/@hex, ';', '')"/>
...