2

文字の16進コードを含む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 の範囲の 16 進数であることを前提としています。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 に答える