2005-10-17 (Mon)

* XSLT 適用時の「リソース '*' の実行エラー」への対処

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML] [IE]

XML ファイルが置いてあるドメインと XSL ファイルが置いてあるドメインが異なっている場合、Internet Explorer のセキュリティ設定によってはエラーが出て XSLT が有効にならないことがある。インターネットオプションで設定することで対処可能。

- アクセスが拒否されました。リソース ' http://sonic64.com/rss.xsl ' の実行エラーです。

当サイト Landscape の RSS http://sonic64.com/cl.xml は、2005-03-16 の「RSS を XSLT で html に変換して見栄え良く表示する」で作成した XSLT http://sonic64.com/rss.xsl を使い、ブラウザで見たときに見やすくなるようにしてある。

しかし、RSS にアクセスすると、以下のようなエラーが表示されるようになってしまった。

XML ページを表示できません
XSL スタイル シートを使用した XML 入力は表示できません。エラーを訂正してください。 [更新] ボタンをクリックするか、または後でやり直してください。

アクセスが拒否されました。リソース ' http://sonic64.com/rss.xsl ' の実行エラーです。

- XSTL 実行時にエラーになる原因を探る

何でエラーになるんだろう? 2005-10-12 の「RSS広告社の広告プログラム Trend Match に参加」したことが原因だろうか? http://sonic64.com/cl.xml にアクセスされたら http://rss.rssad.jp/rss/qArzgZHGLg5Z/rss_0003 に HTTP 302 Moved Temporarily でリダイレクトしているのだが、それが悪いってこと? まさかそんなことはないはず。

Google で アクセスが拒否されました リソース の実行エラーです を検索しても、有力な情報は得られなかった。

おかしいなあ、httpd のアクセスログには XSL ファイルへのアクセスは HTTP Status 200 OK で記録されてる。つまり、XSL ファイルには HTTP 的にアクセスできている。XSLT ってクライアント側で行うものだし、rssad.jp のサーバ設定も関係ない。何だろう?

いろいろ切り分けて考える必要があるな。試しに Mozilla でやってみると、やっぱり XSLT が実行されない。あと、私のサイト sonic64.com 内に別の RSS を置き、同じ XSL を参照すると正常に XSLT が実行される。ということは、RSS や XSL ファイル自体の問題ではないってことだ。クライアント側の問題のような気がする。

IE のオプションで何かあるんじゃないか? 探してみる。あった。

- 「ドメイン間でのデータソースのアクセス」を「有効にする」で IE の XSLT が有効になった

IE だと以下の設定を行うことで、ドメインをまたいだ XML と XSTL による XSLT が有効になる。

IE のメニューバーの「ツール (T)」 の「インターネットオプション (O)を開く。
「セキュリティ」タブを開く。
「インターネット」のアイコンを選択する。
「レベルのカスタマイズ (C)」ボタンを押す。
「その他」カテゴリにある「ドメイン間でのデータソースのアクセス」を「有効にする」を選択。

ちなみに、セキュリティレベルが「中」のとき、「ドメイン間でのデータソースのアクセス」は「無効にする」になっている。

つまり、ドメインをまたがって XSL ファイルにアクセスすることは、セキュリティ的に良くないのでデフォルトで無効にしてあるということか。それもそうか。参照先の XSL ファイルが差し替えられた場合、出力する HTML も差し替えられるということだもんね。

そういえば、amazon は 2004-04-15 の「amazon ウェブサービスでリアルタイムに価格を表示」などのサービスにおいて、XSLT をブラウザ任せにせずにわざわざ HTTP GET している。高度な XSLT プロセッサを提供するというのが第一の理由だろうが、このセキュリティ制限に引っかからないようにするというのも、理由の一つなんだろうな。

2005-04-18 (Mon)

* Bloglines から エクスポートした OPML が文字化けする現象への対処

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [メモ] [RSS] [XML]

http://www.bloglines.com/export にブラウザでアクセスしたとき、XML を正常に表示できない場合がある。原因の一つとして、OPML 中のサイト名に文字化けが発生していることが挙げられる。たとえば IE では以下のようなエラーが表示される。

XML ページを表示できません

XSL スタイル シートを使用した XML 入力は表示できません。エラーを訂正してください。 [更新] ボタンをクリックするか、または後でやり直してください。
-----------------------------------------------------

テキストの内容に無効な文字が見つかりました。リソース 'http://www.bloglines.com/export' の実行エラーです。ライン 971、位置 76

http://www.bloglines.com/export をブラウザに表示させるのではなく、右クリックして直接ファイルに保存すると、該当行付近で盛大に文字化けしているのが分かる。

- OPML の文字化け原因の傾向と対策

私も原因をはっきりつかんでいるわけではないが、文字化けを起こすサイトを見ていると以下の傾向があるように思える。

・サイト名に ASCII 以外の文字が使われている
・サイト名が長い

私は文字化けを起こすようなサイトは Bloglines 上で zz_broken というディレクトリに入れることにしている。Bloglines の OPML エクスポートは ディレクトリ名とサイト名のアルファベット順だ。文字化けを引き起こすサイトの出現位置を最後にすることで、文字化けの影響範囲を最小限にするという狙いだ。ただ、設定によってはアルファベット順にサイトが並ばないかもしれない。そういう場合は文字化けを起こすサイトを OPML の末尾に持ってくる工夫が要る。

RSS のバージョンによっては title の文字数を制限している。もしかしたら、それを無視しているサイトがひっかかっているのかも。

追記。2005-05-13 の「Bloglines で本文が表示されない現象の原因と対処」で述べたことが OPML の文字化けにも関連していると思われる。

2005-04-13 (Wed)

* XML の CDATA 中では ]]> のエスケープが必要

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML] [RSS]

XML の CDATA 中では ]]> のエスケープが必要だ。

- エスケープ必要だよね?

RSS の content::encoded には < や > " をエスケープせずに CDATA として直接記述できる。でも、CDATA の開始や終了を示す <![CDATA や ]]> が登場したらどうなるんだろう? CDATA の終了を判別できなくなるよね。XML というより SGML の規則のような気もするが、調べてみる。

XML用語事典 [CDATAセクション]
http://www.atmarkit.co.jp/aig/01xml/cdata.html
CDATAセクションは、<![CDATA[という文字列で始まり、]]>という文字列で終わる。CDATAセクションの内部には、XMLで利用可能な文字をすべて記述することができる。唯一の例外は]]>という文字列だけで、これを記述することはできない。記述しても、CDATAセクションの終了を示すと解釈されてしまう。

Studying XML -- second step -- [ エスケープ ]
http://www.asahi-net.or.jp/~ps8a-okzk/xml/xml_2/escape.html
 CDATAセクションは、 <や&をエスケープしなくてよい場所ですが、 ]]>という文字列が含まれる場合には ]]&gt;のようにエスケープする必要があります。

あ、やっぱりエスケープしなきゃいけないんだね。

Chalow の RSS 出力部分は私好みになるようにほとんど書き換えてしまってるんだけど、そこでは ]]> のエスケープはやってなかったなあ。まずいな。・・・と思ったけど、データには無条件にhtml エスケープを施してるし、その上で html を追加しているから、Chalow 側で明示的に ]]> を追加しない限り問題ないんだな。

- ]]> を CDATA 中に直接記述する

CDATA 中に ]]> が生で登場したらどうなるか試す。

まずは ]]> が登場しない XML を書いてブラウザに表示させてみる。

<?xml version="1.0" encoding="euc-jp"?>
<sonic>
  <![CDATA[<a href="http://sonic64.com/">Landscape - エンジニアのメモ</a>]]>
</sonic>

うん、問題なく表示された。あたりまえだけどね。で、Landscape に続く - の文字を ]]> に変えてみる。

<?xml version="1.0" encoding="euc-jp"?>
<sonic>
  <![CDATA[<a href="http://sonic64.com/">Landscape ]]> エンジニアのメモ</a>]]>
</sonic>

XML パースエラー: タグの対応が間違っています. 閉じタグが必要です: </sonic>.
URL: file:///d:/tmp/test.xml
行番号: 3, 列番号: 80:  <![CDATA[<a href="http://sonic64.com/">Landscape ]]> エンジニアのメモ</a>]]>
-------------------------------------------------------------------------------^

Firefox で予想通りエラー。^ が示す位置が微妙に違う気がするけど、まあ気にしないでおこう。

XML ページを表示できません
XSL スタイル シートを使用した XML 入力は表示できません。エラーを訂正してください。 [更新] ボタンをクリックするか、または後でやり直してください。


--------------------------------------------------------------------------------

終了タグ 'a' が開始タグ 'sonic' と一致していません。リソース 'file:///d:/tmp/test.xml' の実行エラーです。ライン 3、...

  <![CDATA[<a href="http://sonic64.com/">Landscape ]]> エンジニアのメモ</a>]]>
-----------------...

IE でもエラー。

- ]]> を ]]&gt; にエスケープ

エスケープして記述する。

<?xml version="1.0" encoding="euc-jp"?>
<sonic>
  <![CDATA[<a href="http://sonic64.com/">Landscape ]]&gt; エンジニアのメモ</a>]]>
</sonic>

Firefox での表示。スタイルシートはなし。ところで、エスケープした ]]&gt; を ]]> にアンエスケープしてくれないのかな。
<sonic>
<a href="http://sonic64.com/">Landscape ]]&gt; エンジニアのメモ</a>
</sonic>

IE スタイルシートなしで表示させても同くアンエスケープされない。うーん。まあ Firefox や IE の XML 閲覧機能はおまけみたいなものだから仕方ないかな。
  <?xml version="1.0" encoding="euc-jp" ?>
- <sonic>
- <![CDATA[ <a href="http://sonic64.com/">Landscape ]]&gt; エンジニアのメモ</a>
  ]]>
  </sonic>

2005-03-23 (Wed)

* 巨大な RSS/RDF/Atom を求めて

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [RSS] [XML]

巨大な RSS は男のロマンだという話。

- 108 件のRSS

Dead bookmark - 徹人28号が行く++
http://kitsune.info/blog/?itemid=434
さて、この freshmeat の RSS フィードですが、数ヶ月前まではほんの数件(たしかひと桁だったと思う)しかフィードしてくれませんでした。オープンソースソフトウェアは世界中で日夜開発が続けられているので、これではあっという間にフィードの中身が入れ替わってしまいます。当然見落としがあるでしょうから、これは不便な話でした。

ところがある時から、freshmeat のフィード件数が増えたのです。それもふたつみっつ増えたなんてレベルじゃありません。クリックするとモニタの下限まで行ってまだ余るくらいの数です。今までにいろいろな RSS フィードを見てきましたが、こんなに件数が多いフィードは見たことがありません。freshmeat に登録されているプロジェクトは 3万6千件以上あるらしいので、それもまた当然といえば当然なのですが、それにしても多すぎます。

先ほどふと思い立って、いったい何件フィードされているのか調べてみることにしました。方法は簡単。全フィードを個別のタブで開けばよいのです。私の Firefox は多段タブにしてあるので、全部開けばかけ算でフィード件数がわかります。

……あれ、Firefox が入力を受け付けなくなってしまった。さすがにこんなに開いたらメモリの食い過ぎか?

待つこと 10分。ようやくコントロールを取り戻した Firefox のタブを数えてみました。その数なんと 108枚。まさか 3桁の大台に乗るとは。普通 RSS フィードつーたらあーた、多くても 30件くらいでしょうが。

ちょうど108件なんて、除夜の鐘みたいだ。煩悩が詰まった RSS か。読んでみたいな。

でも、108件のフィードなんて大したこと無いですよ。手前味噌ながら、当サイト Landscape の RSS http://sonic64.com/cl-full.xml にはこの記事を含めて677件のフィードが入ってますから。freashmeat の RSS の約7倍の件数だから、70分あれば Firefox でも開けます。たぶん。

少食な RSS リーダの方には http://sonic64.com/cl.xml がおすすめ。直近7日分の記事しか入れていないので、全記事を格納した RSS に比べてとてもコンパクトです。

- 膨大な情報が詰まったテキストファイルは男のロマン

108件しか入ってないとはいえ、大きな RSS フィードというだけで興味をそそられる。ファイルサイズも巨大だとなお良い。2004-02-17 の「攻殻機動隊 S.A.C. 第5話を見る」でも書いたけど、テキストファイルに膨大な情報が詰まっているっていうだけでワクワクする。男のロマンだ。蛇足だけど、2004-02-17 に書いた「とあるデータファイル」とは、前述の Landscape の 全記事を格納したRSSのこと。

よし、freashmeat の RSS を見に行ってみよう。「俺より強い奴に会いに行く」って感じかな。

- freashmeat の RSS

http://freshmeat.net/ にアクセスすると、右上に XML アイコンがある。これかな。

freashmeat XML アイコンのリンク先
http://download.freshmeat.net/backend/
Files

fm-projects-0.1.dtd Mon May 5 08:14:45 2003  7979 bytes
fm-projects-0.2.dtd Mon May 5 08:15:15 2003  8140 bytes
fm-projects-0.3.dtd Mon Nov 10 00:04:05 2003  9209 bytes
fm-projects-0.4.dtd Mon Jan 3 01:38:10 2005  9454 bytes
fm-projects.rdf.bz2 Wed Mar 23 04:01:38 2005  7172546 bytes
fm-releases-global.xml Wed Mar 23 08:55:14 2005  80365 bytes
fm-releases-handhelds.xml Wed Mar 23 08:55:15 2005  1570 bytes
fm-releases-osx.xml Wed Mar 23 08:55:16 2005  9021 bytes
fm-releases-themes.xml Wed Mar 23 08:55:16 2005  394 bytes
fm-releases-unix.xml Wed Mar 23 08:55:29 2005  79254 bytes
fm-search-0.1.dtd Sun May 5 11:05:31 2002  7774 bytes
fm-search-0.2.dtd Mon Jan 3 01:37:54 2005  9194 bytes
fm-trove-0.1.dtd Tue Nov 4 04:30:30 2003  7113 bytes
fm-trove.rdf Wed Mar 23 04:03:08 2005  10186180 bytes
recentnews.txt Wed Mar 23 08:50:04 2005  953 bytes
rss-0.91.dtd Sun Nov 28 05:07:41 2004  8361 bytes

こりゃすごい。fm-trove.rdf がとくに突き抜けてる。10186180 bytes だって。カンマを振らないと読みにくいな。10,186,180 だから・・・約10メガバイトか。すごいな。当サイトの RSS の約3倍強のサイズだ。これは中も見てみなきゃね。bloglines で読んでみるか。

・・・って、あれ? http://www.bloglines.com/sub/http://download.freshmeat.net/b ... から購読しようとしたけどエラーになっちゃうな。

No feeds were found. Please verify that the website publishes an RSS feed.
あれ? これって RSS じゃないの?

- fm-trove.rdf の中身テキストエディタで見てみる

bloglines で見られないので、ダウンロードしてテキストエディタで開いてみる。

fm-trove.rdf
http://download.freshmeat.net/backend/fm-trove.rdf
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE trove-listing SYSTEM "http://freshmeat.net/backend/fm-trove-0.1.dtd">
<trove-listing>
  <descriminator>
    <id>6</id>
    <name>Development Status</name>
    <parent_id>0</parent_id>
    <root_id>0</root_id>
  </descriminator>
  <descriminator>
    <id>7</id>
    <name>Development Status :: 1 - Planning (disabled category)</name>
    <parent_id>6</parent_id>
    <root_id>6</root_id>
    <projects>
      <project_id>302</project_id>
      <project_id>4754</project_id>
      <project_id>7408</project_id>
      <project_id>8708</project_id>
      <project_id>8805</project_id>
      <project_id>10136</project_id>
      <project_id>12161</project_id>
      <project_id>12568</project_id>
      <project_id>12784</project_id>
      <project_id>12850</project_id>
      <project_id>13629</project_id>
      <project_id>13896</project_id>
      <project_id>13960</project_id>
      <project_id>14018</project_id>
      <project_id>14045</project_id>
      <project_id>14295</project_id>
      <project_id>14408</project_id>
      <project_id>15813</project_id>
      <project_id>15865</project_id>
      <project_id>15919</project_id>
      <project_id>16233</project_id>
      <project_id>16315</project_id>
      <project_id>16339</project_id>
      <project_id>16978</project_id>
      <project_id>16979</project_id>
      <project_id>17218</project_id>
      <project_id>17303</project_id>
      <project_id>17336</project_id>
      <project_id>17337</project_id>
      <project_id>17692</project_id>
      <project_id>17906</project_id>
      <project_id>17966</project_id>
      <project_id>18118</project_id>
      <project_id>18336</project_id>
      <project_id>18759</project_id>
      <project_id>19086</project_id>
      <project_id>19763</project_id>
      <project_id>19923</project_id>
      <project_id>20175</project_id>
      <project_id>20317</project_id>
      <project_id>20329</project_id>
      <project_id>20415</project_id>
      <project_id>21161</project_id>
      <project_id>28022</project_id>
      <project_id>30241</project_id>
      <project_id>30545</project_id>
      <project_id>33206</project_id>
      <project_id>34481</project_id>
      <project_id>34484</project_id>
      <project_id>34517</project_id>
      <project_id>34767</project_id>
      <project_id>36449</project_id>
      <project_id>37421</project_id>
      <project_id>37855</project_id>
      <project_id>38283</project_id>
      <project_id>38800</project_id>
      <project_id>41048</project_id>
      <project_id>44057</project_id>
      <project_id>45123</project_id>
      <project_id>45242</project_id>
      <project_id>45682</project_id>
      <project_id>45747</project_id>
      <project_id>45759</project_id>
      <project_id>46083</project_id>
      <project_id>47001</project_id>
      <project_id>47421</project_id>
      <project_id>48002</project_id>
      <project_id>48778</project_id>
      <project_id>49010</project_id>
      <project_id>49154</project_id>
      <project_id>49984</project_id>
      <project_id>50637</project_id>
      <project_id>50810</project_id>
      <project_id>52002</project_id>
      <project_id>52649</project_id>
      <project_id>52707</project_id>
      <project_id>52747</project_id>
      <project_id>53131</project_id>
      <project_id>53231</project_id>
    </projects>
  </descriminator>

(以下略)

RDF ではあるけど、RSS じゃあないのか。残念。せっかく巨大な RSS に巡り会えたと思ったのにね。

というか、
<!DOCTYPE trove-listing SYSTEM "http://freshmeat.net/backend/fm-trove-0.1.dtd">
ってちゃんと書いてある。同じディレクトリに fm-trove-0.1.dtd などのファイルが置いてある時点で気づくべきだったな。

RSS で最大サイズなのは fm-releases-global.xml かな。
http://download.freshmeat.net/backend/fm-releases-global.xml

サイズは 80365バイト。うーん、大したことないね。「もっと強い奴と戦いたい!」って感じ。

あー、どこかに巨大な RSS や Atom は無いかな。アルバム1枚分の mp3 を Base64 エンコードして RSS に入れて配信するとか・・・これは巨大ではあるけど品性に欠けるか。そうだなあ、Wikipedia の全データを RSS に叩き込むとか、青空文庫の全作品を RSS にして配布するとか、そういうクールでアグレッシブなことをどこかでやってないかなあ。

2005-03-19 (Sat)

* Mozillaで XSLT適用後のDOMのinnerHTML にアクセスするとエラー

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [Mozilla] [XML] [JavaScript]

2005-03-16 の「RSS を XSLT で html に変換して見栄え良く表示する」において、「Mozilla の XSLT プロセッサは disable-output-escaping="yes" を無視する」という現象を書いた。Misc Change Log のいわたさんがいろいろと調査してくださった。ありがとうございます。

- 本家 bugzilla には登録済み

Bug 98168 - <xsl:text disable-output-escaping="yes"> not working
https://bugzilla.mozilla.org/show_bug.cgi?id=98168

すでに本家には登録済みなんですね。bugzilla をチェックすることまでは思いが至りませんでした。
このバグは
Status:  VERIFIED
Resolution:  WONTFIX
になってるってことは、えーと、

Bugzilla の検索フォームを使用するためのヘルプ
http://bluequartz.org/bugzilla-jp/queryhelp.cgi
VERIFIED- QA がバグと処理方法を見た上で、適切な処理がなされたと同意した。
(略)
WONTFIX - 将来にわたって修正されることはないとされた問題。

すなわち修正されないってことが決まったってことですか。ええー、そんなー。

- JavaScript で「Mozilla の XSLT プロセッサは disable-output-escaping="yes" を無視する」に対処する

いわたさんが書いてくださったのが以下の JavaScript。

disable-output-escaping="yes"
http://quasiquote.org/log/2005/03/18/disable-output-escaping
代替案としては上のリンクにあるように、innerHTML をいじればいいのだろうか。

      ...
      </head>
      <script type="text/javascript">
        function onload_cb() {
            var elements = document.getElementsByTagName('div');
            for (var i = 0; i &lt; elements.length; i++) {
                var el = elements[i];
                if (el.className == 'description') {
           el.innerHTML = el.textContent;
                }
            }
        }
      </script>
      <body>
    <xsl:if test="system-property('xsl:vendor')='Transformiix'">
     <xsl:attribute name="onload">onload_cb()</xsl:attribute>
    </xsl:if>
    <div class='description'>
     <xsl:value-of select="content:encoded" disable-output-escaping="yes"/>
    </div>
    </p>
      ....


みたいにしてみたけど、innerHTML に代入するところで例外吐いて死ぬ。ううむ。

確かにエラーになりました。Mozilla/5.0 (Windows; U; Windows NT 5.0; ja-JP; rv:1.7.5) Gecko/20041108 Firefox/1.0 です。でも何でだろう? el.innerHTML = el.textContent; の右辺の el.textContent を固定文字列に変えてもエラーになるので、innerHTML のアクセス時の例外か。

Firefox の JavaScript コンソールに表示されたエラー
エラー: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIDOMNSHTMLElement.innerHTML]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: file:///E:/cygwin/home/sonic/public_html/log/cl.xml :: onload_cb :: line 6"  data: no]

- XSL 変換後文書の DOM ツリーをチェックしてみる

Firefox 付属の DOM インスペクタで XSL 変換後の文書の DOM ツリーを確認したが、問題なさそうだ。エラーになる原因として考えられるのは、XSL 適用後の DOM ツリーの場合、innerHTML にはアクセスできないという制約または仕様の存在かなあ。

html に XSL 変換後の文書をハードコーディングしたときはちゃんと el.innerHTML = el.textContent; が動作する。以下の html を euc-jp で保存して Firefox にレンダリングさせたら、エスケープした h1 がちゃんとエスケープ解除されて html としてレンダリングされた。つまり、JavaScript 自体には問題がないということだ。

<html lang="ja"><head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<!-- 京 -->
<title>Landscape - エンジニアのメモ</title>
<link rel=stylesheet href="diary.css" media="all">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

    <script type="text/javascript">
        function onload_cb() {
            var elements = document.getElementsByTagName('div');
            for (var i = 0; i < elements.length; i++) {
                var el = elements[i];
                if (el.className == 'sec_body') {
                  el.innerHTML = el.textContent;
                }
            }
        }
    </script>

</head>
<body onload="onload_cb()">
<div class="day">
<p class="pdate"><span class="date"><a name="2005-03-16" href="2005-03-16.html">2005-03-16 (Wed)</a></span></p>
<div class="body">

<div class="section">
<div class="subtitle"><h2><a name="2005-03-16-1" href="2005-03-16.html#2005-03-16-1"><span class="sanchor">*</span></a> <strong class="clitemheader">XML: RSS: RSS を XSLT で html に変換して見栄え良く表示する</strong></h2><p>この記事の直リンクURL: <a href="2005-03-16.html#2005-03-16-1" title="この記事にリンクする場合などに使う恒久的な URL">Permlink</a> | この記事が属するカテゴリ:  [<strong><a href="cat_xml.html" title="XML カテゴリの記事一覧">XML</a></strong>] [<strong><a href="cat_rss.html" title="RSS カテゴリの記事一覧">RSS</a></strong>]</p></div>
<div class="sec_body">

&lt;h1&gt;H1&lt;/h1&gt;

</div>
</div>
</div>
</div>
</body>
</html>

うーん、今回は有効な対処法がなかったなあ。Google で disable-output-escaping を検索したら、属性値のエスケープを解除する裏技的な方法はあったんだけど、私がやりたいことには応用できなさそうだし。

属性値のエスケープ無効化 - XML & SOA
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=1206 ...
飛騨の職人さんのような、手作りも現在は可能です。
[xml-users 8826] Re: MSXMLと.NETFramework ClassLibraryのXSLT変換の相違
http://www2.xml.gr.jp/log.html?MLID=xmlusers&TID=8815

<xsl:for-each select = "@*">
<xsl:text> </xsl:text>
<xsl:value-of disable-output-escaping="yes" select="name()" />
<xsl:text>=</xsl:text>
<xsl:text disable-output-escaping="yes">"</xsl:text>
<xsl:value-of select="." />
<xsl:text disable-output-escaping="yes">"</xsl:text>
</xsl:for-each>

XSLT !斬り!

とりあえず今回はお手上げ。

2005-03-16 (Wed)

* RSS を XSLT で html に変換して見栄え良く表示する

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML] [RSS]

Landscape の RSS に XSL (スタイルシート) を付けて、RSS を XSLT (XSL Transformations) を施した html として表示するようにした。

- XSLT で RSS を見栄え良く

当サイト Landscape は直近7日分の記事の全文入り RSS と、全記事・全文入りの RSS を配布している。

直近7日分の記事全文を含む RSS
http://sonic64.com/cl.xml

すべての記事全文を含む RSS
http://sonic64.com/cl-full.xml

これらは生の XML ファイルなので、そのままブラウザで閲覧しようとすると XML データがそのまま表示される。Mozilla などで Landscape の RSS を表示すると、以下のように「XSL が無いから仕方なく XML ドキュメントツリーを表示するよ」といった主旨のメッセージが表示される。
この XML ファイルにはスタイル情報が関連づけられていないようです。以下にドキュメントツリーを表示します。

実際に RSS のデータを利用するときは Bloglines や RSS リーダーで処理して表示させることがほとんどだと思われるので、 XSL が無くても問題はない。ただ、XSL があった方がブラウザで生の XML データを表示させたときに見やすい。というわけで、XSL を書いて RSS を html に変換して表示するようにしてみる。

- 先達の知恵を使え

ゼロから XSL を書き起こすのは大変そうなので、先達の書いた XSL を修正して自分好みの XSL を作ることにする。

日本で RDF/RSS やセマンティックウェブといったら The Web KANZAKI http://www.kanzaki.com/ だ。http://www.kanzaki.com/info/memo.xsl を参考に Landscape の XSL を記述する。

- RSS の content:encoded を XSL 変換後の文書に表示

2004-10-26 の「content:encodedが足りねぇ… じゃんじゃん 持ってこい」で書いたように、私は RSS に記事全文を入れる派だ。なので、今回の XSL でも content:encoded のデータをそのまま表示させるようにしたいところだ。

Web KANZAKI の XSL は content:encoded ではなく description を表示するようにしているので、ここは修正が必要。以下のようにした。

content モジュールの指定を追加。
description を呼び出している部分を content:encoded を呼ぶようにし、disable-output-escaping 属性を属性値 yes で追加。

  xmlns:content="http://purl.org/rss/1.0/modules/content/"
(略)
<xsl:value-of select="content:encoded" disable-output-escaping="yes"/>

- 完成した XLS

html で使っていたスタイルシート (CSS) を XSL 変換後の文書にも流用したかったので、同じような論理構造で html を出力するように XSL を仕上げた。以下に仕上げた XSL を引用しておく。favicon を呼び出すための記述なども追加しておいた。

http://sonic64.com/rss.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:rss="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  exclude-result-prefixes="rdf rss dc content"
>

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

<xsl:template match="rdf:RDF">
  <html xml:lang="ja" lang="ja">
  <head>
    <title><xsl:value-of select="rss:channel/rss:title"/></title>
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <link rel="stylesheet" href="diary.css" type="text/css" />
    <link rel="alternate" type="application/rss+xml" title="RSS" href="http://sonic64.com/cl.xml" />
    <link rel="alternate" type="application/rss+xml" title="RSS full archive" href="http://sonic64.com/cl-full.xml" />
    <link rel="shortcut icon" href="favicon.ico" />
  </head>
  <body>
    <h1><a href="{rss:channel/rss:link}"><xsl:value-of select="rss:channel/rss:title"/></a></h1>

    <p><a href="{rss:channel/rss:link}"><xsl:value-of select="rss:channel/rss:title"/></a> の記事<xsl:value-of select="count(rss:item)"/>件の全文です。RSS フィードを XSL 変換して表示しています。この RSS フィードをお使いの RSS リーダーに登録すれば <a href="{rss:channel/rss:link}"><xsl:value-of select="rss:channel/rss:title"/></a> の RSS を購読できます。</p>

    <xsl:apply-templates select="rss:item"/>

    <p class="credit">斎藤 宏明 <a href="mailto:sonic64@infoseek.jp">sonic64@infoseek.jp</a></p>
  </body>
  </html>
</xsl:template>

<xsl:template match="rss:item">
  <div class="day">
  <p class="pdate"><span class="date"><a href="{rss:link}"><xsl:value-of select="substring(dc:date, 1, 10)" /> </a></span></p>
  <div class="section">
    <div class="subtitle"><h2><a href="{rss:link}"><span class="sanchor">*</span></a> <strong class="clitemheader"><xsl:value-of select="rss:title"/></strong></h2>
    </div>
    <div class="sec_body">
    <xsl:value-of select="content:encoded" disable-output-escaping="yes"/>
    </div>
  </div>
  </div>
</xsl:template>

</xsl:stylesheet>

- RSS にスタイルシートを呼び出す記述を追加

RSS からスタイルシートを呼び出すための記述を追加する。

以下を RSS に追加するだけ。非常に簡単。
<?xml-stylesheet href="rss.xsl" type="text/xsl" media="screen"?>

- Mozilla の XSLT プロセッサは disable-output-escaping="yes" を無視する

Mozilla で動作確認をしてみると、content:encoded 部分が意図したとおりに表示されない。content:encoded 中の html タグがエスケープされているような動きをしている。

エスケープされるのを防ぐために、disable-output-escaping="yes" を追加しておいたが、それが効いていないようだ。
<xsl:value-of select="content:encoded" disable-output-escaping="yes"/>

どうやら、Mozilla に搭載されてる XSLT プロセッサは disable-output-escaping="yes" の指定を無視するようだ。その結果、content:encoded の中身がそのまま表示されてしまうわけだ。この現象は Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP; rv:1.7.5) Gecko/20041108 Firefox/1.0 の環境で発生した。

なんとかならないかなあ。JavaScript を使って UserAgent が Mozilla のときは document.write でレンダリングさせたりすればいいのかな。なんか手間がかかるなー。仕方ないので今回はとくに対処しないことにする。

追記。2005-03-19 に「Mozillaで XSLT適用後のDOMのinnerHTML にアクセスするとエラー」を書いた。結局問題は解決できなかったけど。

- xsl:output を付けると IE6 で文字化け

実は IE でも問題が発生していた。

<xsl:output method="html" encoding="utf-8" />
XSL に上記の指定を付けると WindowsXP の IE6 では盛大に文字化けしてくれる。どうやら出力を Shift_JIS として解釈してる模様。仕方がないので、xsl:output は指定しないことにした。

- さあ XSLT 付きの RSS を見てみよう

さあ、丹誠込めて作った XSL を適用した RSS をぜひ見て欲しい。

直近7日分の記事全文を含む RSS
http://sonic64.com/cl.xml

すべての記事全文を含む RSS
http://sonic64.com/cl-full.xml

直近7日分の方はせいぜい数十KB のサイズなのですぐにレンダリングされるけど、すべての記事全文の方はかなり重い。そもそも RSS 自体が 3MB 程度もあるからなー。

で、なにが便利なの? って聞かれるとちょっと困る。

「すべての記事全文を含む RSS」の方は利用価値があるかも。ブラウザの検索機能などを使って全文検索をしたいときに使えるだろうしね。あとは、Landscape の中身を全部印刷して読みたいときとかに有用かな。たぶん合計で数百ページ以上になると思うけど。

- 今後の野望

今回は比較的質素な XSL を書いたが、もっといろんな機能を盛り込んだ html を出力する XSL を書いても面白いかも。Google の検索窓を付けたり、amazon のライブリンク付けたり、記事一覧を付けたりして html 版と同じような見た目を再現してみようかな。あんまり意味ないけどね。

あとは http://sonic64.com/rss.xsl にアクセスすると生の XML 文書が表示されるのはなんか中途半端なので、XSL を XSL で見栄え良くするというのはどうだろう。

2004-04-16 (Fri)

* amazon が値引きしてる場合に割引率を表示する XSLT

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML] [amazon]


2004-04-15 の 「アマゾンウェブサービスでリアルタイムに価格を表示」で書いた XSLT をちょっと改良。アマゾンが値引きしている場合に、何パーセント値引きしているかを示すために割引率を表示するようにした。

こんな感じ。特に割引されていないときは普通の表示のまま。


- XSLT ソースから抜粋

http://sonic64.com/dat/aws-price.xsl
<html lang="ja"><head>
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" href="http://sonic64.com/diary.css" media="all" />
<title>Landscape: Amazon webservice stylesheet</title>
</head><body class="aff_xsl">
定価: <xsl:value-of select="$listprice"/><br />

<xsl:variable name="num_listprice" select="number(translate(translate($listprice, '¥', ''), ',', ''))"/>
<xsl:variable name="num_ourprice" select="number(translate(translate($ourprice, '¥', ''), ',', ''))"/>
<xsl:variable name="discount" select="$num_listprice - $num_ourprice"/>

<xsl:choose>
  <xsl:when test="0 &lt; $discount">
    アマゾン価格: <span class="aff_discount"><xsl:value-of select="$ourprice"/> (<xsl:value-of select="round(($discount div $num_listprice) * 100)" />% 引き)</span>
  </xsl:when>
  <xsl:otherwise>
    アマゾン価格: <xsl:value-of select="$ourprice"/>
  </xsl:otherwise>
</xsl:choose>

静的 html 生成のページでもここまで表現できるなんて素晴らしい。

2004-04-15 (Thu)

* amazon ウェブサービスでリアルタイムに価格を表示

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML] [amazon]

アマゾンのウェブサービスと独自 XSLT を組み合わせると、好きなフォーマットでアマゾンのデータを利用できる。これを上手く利用したアフィリエイト用 html 生成ツールが以下のサイトにある。

アマゾン アソシエイトの便利ツール:HTML自動作成
http://www.goodpic.com/mt/aws/

価格部分と在庫状況表示部分は iframe でリアルタイムにアマゾンから取得している。確かにこれなら「価格はライブリンクかウェブサービスで取得したもののみ表示可」という規約にも抵触しない。「でも、iframe だと CGI 呼び出しが必要なのでは?」と思ったら、アマゾンは XSLT プロセッサまで提供してるので CGI を自前で用意しなくても利用できるとのこと。これは知らなかった。

- 価格表示部分の文字化け

で、これを Landscape に組み込んだところ、価格表示部分が文字化けしてしまった。iframe のソースを見ると、XSLT を適用した上でアマゾンから送られてくるデータは html として成り立っていないし、エンコードが utf-8 になっている。Content-Type などの情報が無いのでブラウザが文字コード判定に失敗しているのだろう。

Landscape は ページを euc で記述しているので、euc と utf-8 が混在している環境だから文字化けしているのかもしれないが、よく考えれば iframe はそれだけで独立した html になっていなければならないはずだ。逆に言うと、独立した html として成立しないデータだからブラウザが判別に失敗していると考えられる。正しい html を出力するようにすれば、ブラウザの文字コード自動判別機能が正しく機能して文字化けを解消できるかもしれない。

- XSLT を修正して文字化けを回避

html 要素、head 要素、title 要素、body 要素を記述。初めは meta に Content-Type の指定を入れたのだが、アマゾンの XSLT プロセッサが自動的に Content-Type を出力してくれているようだ。html っぽいデータだと自動的に入れてくれるのだろうか?

XSLT を修正してテストしてみると・・・。おおっ、文字化け無しの出力が得られたぞ。

Landscape の音楽カテゴリも全部書き換えて、ばっちり価格と在庫状況が表示されるようになった。
音楽 - Landscape
http://sonic64.com/cat_e99fb3e6a5bd.html

今回書いた XSLT
http://sonic64.com/dat/aws-price.xsl

で、コメントとして goodpic に投稿した。

AmazonアフィリエイトHTML作成ツールを更新
http://www.goodpic.com/mt/archives/000496.html

- レイアウトは改良の余地あり

iframe 部分と周りの要素を、もうちょっと柔軟に配置できると良いんだけどなあ。今のままだとちょっと間延びしたレイアウトになってしまう。スタイルシートなどを工夫して何とかしてみよう。

2003-10-30 (Thu)

* XBRL で使われる用語についてメモ

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [XML]

結局は XML の用語だけど。

- XML Schema

文書構造定義。DTD はスキーマの一種。
XML Schema では、データ型や名前空間など DTD よりも高度な機能が定義されている。
スキーマって懐かしい響きだな。社会学の「準拠枠」を思い出すよ。

- XLink

リンク。オブジェクト間を連結するもの。かなり多機能で抽象的な概念。
HTML の <a href="http://www.google.co.jp/">Google</a> は単純一方向リンク。
XLink ではさらに 多方向へのリンクや双方向のリンクも定義できる。
また、外部のファイルでリンク情報を定義し、文書と分離することもできる。

すべての記事の見出し (全1029件)
全カテゴリの一覧と記事の数
カテゴリごとに記事をまとめ読みできます。記事の表題だけを見たい場合は、すべての記事の見出し (カテゴリ別表示) へ。

直近30日分の記事
2007-04-23 (Mon)
2007-03-07 (Wed)
2007-02-27 (Tue)
2007-01-17 (Wed)
2007-01-15 (Mon)
2007-01-14 (Sun)
2007-01-08 (Mon)
2006-12-01 (Fri)
2006-11-22 (Wed)
2006-11-20 (Mon)
2006-11-19 (Sun)
2006-09-30 (Sat)
2006-08-29 (Tue)
2006-08-04 (Fri)
2006-07-27 (Thu)
2006-07-23 (Sun)
2006-07-17 (Mon)
2006-07-10 (Mon)
2006-07-06 (Thu)
2006-07-03 (Mon)
2006-06-29 (Thu)
2006-06-28 (Wed)
2006-06-27 (Tue)
2006-06-25 (Sun)
2006-06-19 (Mon)
2006-06-18 (Sun)
2006-06-15 (Thu)
2006-06-11 (Sun)
2006-06-01 (Thu)
2006-05-30 (Tue)
プロファイル
斎藤 宏明。エンジニアです。宇都宮市に住んでいます。
リンク
RSS
スポンサードリンク
Powered by
さくらインターネット

© 斎藤 宏明 Saito Hiroaki Gmail Address
Landscape - エンジニアのメモ http://sonic64.com/
Landscape はランドスケープと読みます。
ひらがなだと らんどすけーぷ です。