在xslt中插入html-entities

时间:2010-06-27 10:08:52

标签: xslt entities

我有一些包含字符十六进制代码的XML,例如它是这样的:

<char hex="AB"/>

现在我想要在浏览器中显示XSLT转换:

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

但是,浏览器中的输出为&amp;#xAB;,而不是我预期的&#xAB; 所以浏览器不会显示该代码的字符(可能是«),而只显示文字字符串&#xAB;

如何让XSL不要逃脱&符号?

2 个答案:

答案 0 :(得分:1)

如果您将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 (禁用输出转义),但此“功能”在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,则需要将更多code个元素相应地添加到my:hex元素

答案 1 :(得分:0)

我认为你的问题不仅仅是逃避问题,而是the disable-output-escaping attribute怎么样?

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