2005 年 3 月の履歴(もしくは日誌)


2005 年 3 月

3 月 4 日

STX を試してみました

STX ってものがあるのを知ったので,試してみました.STX は XSLT のように XML を処理して変換するためのものです.XSLT が XML のツリー構造を元にして,別の XML ツリー構造を構築するのに対して,STX では SAX みたいにイベントを元にして動くのだとか.ぱっと見た目は STX スタイルシートのソースは XSLT のそれと似ているので,すぐ理解できるかなって思って試してみたのです.試してみたら,なるほど,その違いがなんとなく感じられました.

まず試しに RSS 1.0 を XHTML に変換する STX スタイルシートを書いてみました.XSLT でならすぐに書けるような簡単なのを選びました.

試してみてすぐにつまずいたのは,STX では <stx:value-of select="rss:title"/> ってやっても rss:title の内容がとれない事です.XSLT では入力の XML のツリーを作ってから XPath でたどって行くのですが,XST では処理中のカレントノードの内容以外は,まだ処理していないか,すでに過ぎ去ってしまったかのどっちかなので,そういうものなのですな.

で,どうやるかというと,まず現在のノードの子ノードを処理して,必要なものが見つかったら変数とかバッファとかに格納しておいて,あとから利用するらしいです.
例えばこんな感じ:

<stx:variable name="title" />

<stx:template match="rss:item">
  <stx:process-children />
  <li><stx:value-of select="$title"/></li>
 </stx:template>

<stx:template match="rss:title">
  <stx:assign name="title" select="." />
</stx:template>

で,こんな感じになります.
rss:item っていうノードがあったぜってイベントが発生して,それが rss:item のテンプレートにマッチします.
でテンプレートの中身を処理します.
すると<stx:process-children />があるので小ノードを処理.
すると rss:title を発見して,それが rss:item のテンプレートにマッチ.
そのテンプレートでは,rss:title の内容を title っていう変数に入れます.
全ての rss:item の子ノードの処理が終わったら,rss:item がマッチしていたテンプレートに戻ってきて処理を続けます.
このときに title に値が入っているので,<stx:value-of select="$title"/> で title の値を読めるわけです.

このように XSLT ではデータのツリーに対して処理しているのに対して,STX ではデータの流れ (stream) に対して処理するのが違うのですね.

スタイルシートのソースの見た目は XSLT に似ているけど,データの扱いが全然違います.ちょっと試してみて違いはなんとなく分って来ましたが,こういった例では STX の XSLT に対する利点は見えてこないですね.さてはて.

以下は書いてみた RSS 1.0 を XHTML に変換する STX スタイルシート:

<?xml version="1.0" encoding="utf-8"?>
<stx:transform version="1.0"                               
  xmlns:stx="http://stx.sourceforge.net/2002/ns"
  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/"
  exclude-result-prefixes="rdf rss"
  strip-space="no"
>

<stx:variable name="title" />
<stx:variable name="link" />
<stx:variable name="description" />
<stx:variable name="i" select="0"/>

<stx:template match="rss:channel">
  <html>
    <stx:process-children />
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <title><stx:value-of select="$title"/></title>
    </head>
    <body>
      <ul>
        <stx:process-siblings />
      </ul>
    </body>
  </html>
 </stx:template>

<stx:template match="rss:item">
  <stx:process-children />
  <stx:assign name="i" select="$i + 1" />
  <li>
    <a>
      <stx:attribute name="href">
        <stx:value-of select="$link"/>
      </stx:attribute>
      <stx:attribute name="id">
        <stx:text>d</stx:text>
        <stx:value-of select="$i"/>
      </stx:attribute>
      <stx:value-of select="$title"/>
    </a>
    <br />
    <stx:value-of select="$description"/>
  </li>
 </stx:template>

<stx:template match="rss:title">
  <stx:assign name="title" select="." />
</stx:template>

<stx:template match="rss:link">
  <stx:assign name="link" select="." />
</stx:template>

<stx:template match="rss:description">
  <stx:assign name="description" select="." />
</stx:template>

</stx:transform>

過去の STX の話題:

http://onohiroki.cycling.jp/tb/tb.cgi/weblog_d20050304n1 TrackBack