2

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

<char hex="AB"/>

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

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

但是,浏览器中的输出&amp;#xAB;与我预期&#xAB; 的不同,因此浏览器不显示该代码的字符(应该是«),而只显示文字字符串&#xAB;

我怎样才能让 XSL 不逃避 & 符号?

4

2 回答 2

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元素

于 2010-06-27T13:47:57.063 回答
0

我认为您的问题不仅仅是转义,但是属性disable-output-escaping

<xsl:value-of disable-output-escaping="yes" select="concat('&amp;#x', /char/@hex, ';', '')"/>
于 2010-06-27T10:41:28.653 回答