IE 5.XのXSLTで生成したファイルが文字化けする
IE 5.0/5.5とMSXML4を利用して、XSLTで生成したHTMLに日本語を含むURIを入れようとすると、文字化けしてしまいます。解決方法を教えてください。

回答/富士ソフトABC株式会社 技術センター
2001/12/7

 まず、この問題をできるだけ小さいファイルで再現できるようにしたのが下記のリスト1とリスト2です。ご質問にあるように、この2つを組み合わせて実行すると、HTML文書として生成されるアンカーの参照先が文字化けしてしまいます。

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<PAGE>
  <EMPLOYEES>
    <EMPLOYEE>
      <ENAME>あああ</ENAME>
    </EMPLOYEE>
    <EMPLOYEE>
      <ENAME>いいい</ENAME>
    </EMPLOYEE>
    <EMPLOYEE>
      <ENAME>ううう</ENAME>
    </EMPLOYEE>
  </EMPLOYEES>
</PAGE>
リスト1 実際にはUTF-8のファイル(Test.xml)。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user1="usernamespace1"
version="1.0">
  <xsl:output indent="yes" method="html" encoding="UTF-8"/>
  <msxsl:script language="JScript" implements-prefix="user1">
    <![CDATA[
    function test(){
      return "#漢字"; // ここをどうすべきか?
     }
    ]]>
  </msxsl:script>

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

  <xsl:template match="PAGE">
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </html>
  </xsl:template>

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

  <xsl:template match="EMPLOYEE">
    <a>
      <xsl:attribute name="href">
        <xsl:value-of select="user1:test()"/>
      </xsl:attribute>
      <xsl:value-of select="ENAME"/>
    </a>
    <br/>
  </xsl:template>

</xsl:stylesheet>
リスト2 実際にはUTF-8のファイル(Test.xsl)。

 ご質問のポイントを絞ってみると、上記のリスト1のXML文書を、リスト2のXSLTで変換すると、以下の変換結果が出力されることを期待しているはずです。

<a href="#漢字">あああ</a><br />
<a href="#漢字">いいい</a><br />
<a href="#漢字">ううう</a><br />

 しかしこのHTML文書をHTML 4.01の勧告に厳密に従って記述すると次のようになり、意図したとおりの結果とはなりません。

<a href="#%E6%BC%A2%E5%AD%97">あああ</a><br />
<a href="#%E6%BC%A2%E5%AD%97">いいい</a><br />
<a href="#%E6%BC%A2%E5%AD%97">ううう</a><br />

 なぜ漢字が文字コードになってしまうかというと、HTMLにはアンカータグの「href」アトリビュートを記述するときに、「URIの値が非ASCII文字だった場合エスケープすべきである」という決まりがあるからです。W3C勧告「HTML 4.01 Specification」のB.2.1 Non-ASCII characters in URI attribute valuesに記述があります。

 しかしXSLTに限れば、ご質問にあるような考え方、つまり漢字での出力を期待することは、決して誤りではありません。試しに下記にあるように、アンカータグをイメージタグに、hrefアトリビュートをaltアトリビュートに置き換えて確認してみてください。きちんと非ASCII文字列「#漢字」が格納されていることが分かります。

<a>
<xsl:attribute name="href">
<xsl:value-of select="user1:test()"/>
</xsl:attribute>
<xsl:value-of select="ENAME"/>
</a>

↓上記を下記のように書き換える

<img>
<xsl:attribute name="alt">
<xsl:value-of select="user1:test()"/>
</xsl:attribute>
</img>

 このことからも、MSXMLがXSLTの勧告に従って厳格に実装されていることが分かります。

 つまり今回の回答は、「この動作はHTMLの仕様です」となるのですが、実際には簡単な解決策があります。それを紹介します。xsl:outputのmethodをhtmlからxmlに変更すればいいのです。

<xsl:output indent="yes" method="html" encoding="UTF-8"/>

↓下記のように書き換える

<xsl:output indent="yes" method="xml" encoding="UTF-8"/>

 XMLでは「アンカータグのhrefアトリビュートが特殊である」ことはまったく関係ありませんので、上記のように書き換えて処理すれば、きちんと意図したとおりの結果を得ることができます。

 この変換結果を、XHTMLと仮定してXSLTスタイルシートを記述すればHTMLとの食い違いも少ないので、xsl:output の method を変更したことによる問題も発生しないはずです。

■関連記事
XSLTスタイルシート書き方講座 (1) XSLTスタイルシートの基礎の基礎

サンプルで覚えるXSLTプログラミング

 

「Ask XML Expert」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間