目次


実用的なXML:XSLT 2.0とXQueryの比較

異なるタスクに使用可能なXPathの2つの方言

Comments

標準策定中

1999年11月に紹介されて以来、XSLT(XSL Transformations language)はXMLドキュメントを操作するための、かなり便利なツール(最も便利ではないとしても)だと思ってきました。Javaやその他の言語で書かれたXMLドキュメントに対し、多くのAPIやツールが入手可能であり、さまざまなプロジェクトで使用してきましたが、XSLTを少しも使用しなかったXMLプロジェクトというものは思い出せません。

私は、当然のように、XSLT 2.0の進展を多大な興味を持って追いかけてきました。XSLTはパワフルな言語であり、最も複雑な操作も扱えるだけの高度な機能を備えていますが、非常に冗長でもあり、そのためにデバッグや大きなスタイルシートの保守が困難です。W3Cは、XSLT 2.0とXQuery 1.0の2つの言語をリリースするときに、この問題やその他の問題を解決したいと考えています。この記事では、これら2つの最新言語を比較して、使いこなしのヒントを示します。

この記事の執筆時点で、XSLT 2.0とXQuery 1.0のステータスはCandidate Releaseです。これは、まもなく採択される標準を表すW3C用語です。どのくらい「まもなく」かは、レビュー・プロセスしだいです。

大量のオーバーラップ

設計により、XSLT 2.0とXQuery 1.0には多くの共通点があります。どちらの言語もXPath 2.0を基礎とし、XMLドキュメントの操作を目的としています。どちらの言語も、単純なタスクのために使用するインタープリター型言語のスクリプトの概念を借用しています。実際には、どちらの言語を使用しても、特定の結果を得ることができます。一方が他方よりも優れているということはありません。また、それぞれの言語が独自の性格を持っています。そのときどきのタスクに応じて、また、おそらく開発者の性格に応じて、どちらかが使いやすいということはあるでしょうから、両方を知っておくことは意味のあることです。

この記事では、開発者のスタイルと作業内容に適した方を選べるように、各言語の共通性と独自性に焦点を当てます。

XPath基礎

では、XPath 2.0から始めましょう。XSLTは常に2つの言語、すなわち、XPath言語とXSLTそのものが1つのパッケージになっています。XPathは、属性を選択するときに要素を問い合わせたり、テンプレート・マッチ(XSLTのmatch属性)を指定するために使用する言語です。XSLT言語そのものは、xsl:apply-templates、xsl:value-of、xsl:for-eachなどの命令による変換結果を指定するために使用する言語です。

リスト1のXSLTテンプレートを見てください。これには、XPath言語(属性のmatchとselect)、XSLTそのものの要素(templateおよびxsl:value-of命令)、結果としての言語の要素(htmlおよびhead)が混在しています。

リスト1.XSLTテンプレート
<xsl:template match="rss">
   <html>
      <head><title><xsl:value-of select="channel/title"/></title></head>
      <xsl:apply-templates/>
   </html>
</xsl:template>

XPathとXSLTでのタスクの分離は新しいことではありませんが、他の言語はXPathを基礎としていないため、XQueryが登場するまでは、ほとんど学術的な区別でした。

XPath 2.0は大きくアップグレード

XPath 2.0は非常に意味のあるアップグレードです。XPath 1.0では、XMLドキュメントのノードだけしかクエリーを実行することができませんでした。XPath 2.0はシーケンスに作用し、シーケンスにはノードを含めることができるだけでなく(大きく変わるわけではありません)、文字列、整数、その他のアトミックな値を含めることもできます。わずかな違いのようですが、重要な違いです。2次クエリーによってクエリーの結果を掘り下げることも可能になりました。これまでのXSLT 1.0では、2つのクエリーを連鎖するには、プロプライエタリーな関数が必要でした。

XPath 2.0のもうひとつの重要な変更に、ループと変数のサポートがあります。言い換えると、XPathで変数を宣言して、XPathから値を代入することができます。ループについても同様で、XPathでループを実行してリターン値を計算することができます。たとえば、単価に数量を掛けて、請求の行を処理できます。今まで同様、XSLTで変数を宣言することもでき、XSLTでのループも強化されています。このアップグレードには、大量のパワーが詰め込まれています。

新しいオプションによって、XSLTのスタイルシートが大幅に単純化されます。XSLT 1.0では、多くのアルゴリズムを(単純なものだとしても)繰り返し書かなければなりません。たとえば、請求書の合計を計算するといった、ありふれた処理でも、再帰アルゴリズムが必要です。XSLT 2.0では、このような必要がなくなりました。それは主に、XPath 2.0の新機能のおかげです。

XQuery対XSLT

XSLTスタイルシートは、XML操作のために使用されます。個人的には、XSLTをWebサイト・パブリッシングに使用しています。レポートの作成、統計の計算、XMLファイルの前処理、異なるボキャブラリーまたはソフトウェアの間の変換、データベースにインポートするためのデータの作成、データベースからのエクスポートの処理、Webサービス要求への応答などに使用しています。

実際、この言語を乱用しているといってもいいでしょう。たしかに役に立ちますが、ときには嫌気が差すこともあります。その結果、スタイルシートには多くの再帰関数が含まれ、デバッグが困難です。

問題は、その名が示唆するように、XSLTは何よりもパブリッシング用のドキュメントの変換を目的としていることです。XSLTは、汎用の照会言語として作成されたものではありませんが、他に良い選択肢がないので、しばしば照会言語として使用されてきました。一方、XQueryは、ドキュメントに照会して、レポートを作成することを目的としています。

異なるフレーバー

実を言えば、変換(transform)と照会(query)は、多くのアプリケーションをカバーする汎用的な用語です。すでに述べたように、2つの言語はともにXPath 2.0を基礎としているため、同じような機能を備えています。しかし、使用パターンが異なるため、それぞれ適したタスクというものがあります。

XSLTの設計者が前提としていたのは、利用者はドキュメントの処理に興味があるということでした。パブリッシングに関して言えば、これは妥当な前提です。したがって、XSLTにはツリー・ウォーキング・エンジンが組み込まれていて、デフォルトではドキュメント全体を処理します。また、ほとんどがテキスト情報であるということも前提となっていました。したがって、XSLTは強い型付き言語ではありません。そして最後に、マークアップ言語でドキュメントを生成することが前提となっているので、XSLTはXMLボキャブラリーとして作成されています。

XQueryの設計者は、別の前提に立っています。彼らが前提としたのは、クエリーを実行するときには、ドキュメントの数セクションに的を絞ることが望ましいということでした。そのため、この言語はXPathクエリーを中心に構築されています。XQueryにはデフォルトの動作はありません。利用者しだいです。

また、データベースの抽出(database extract)など、型付きデータの操作が前提となっているため、XQueryは強い型付き言語です。最後に、構文は明らかにXMLではありません。

XSLT 2.0とXQuery 1.0の違いを説明するために、例を見てみましょう。

2つの言語を比較するには、一般に同じアルゴリズムを2つの言語で書きますが、この例ではフェアではないでしょう。それぞれの言語には、それぞれ他の言語に勝る得意なタスクがあるので、1つの例だけでは偏見を与えることになります。そこで、私は2つの例を用意することにしました。XSLTについては変換の例、XQueryについてはクエリーの例です。これらを比較することによって、ニーズに適した言語があることを理解できるでしょう。

XMLドキュメント

どちらの例もリスト2で実行しています。RSSの記事のリストです。

リスト2.記事のリスト
<?xml version="1.0"?>
<rss version="2.0">
 <channel>
  <title>Projects in the "Working XML" column</title>
  <description>A selection of ben's article on
     developerWorks.</description>
  <language>en</language>
  <link>http://www.ibm.com/developerWorks/xml</link>
  <item>
   <title>Safe coding practices</title>
   <pubDate>Fri, 6 May 2005 00:00:00 GMT</pubDate>
   <link>http://www.ibm.com/developerworks/xml/library/x-wxxm30.html</link>
   <description>Most common pitfalls and how to avoid them (4 parts).</description>
  </item>
  <item>
   <title>The Eclipse task list</title>
   <pubDate>Fri, 22 Oct 2004 00:00:00 GMT</pubDate>
   <link>http://www.ibm.com/developerworks/library/x-wxxm27/</link>
   <description>Various techniques on integrating XML and Eclipse (4 parts).</description>
  </item>
  <item>
   <title>XML, XMI and code generation</title>
   <pubDate>Wed, 31 Mar 2004 00:00:00 GMT</pubDate>
   <link>http://www.ibm.com/developerworks/xml/library/x-wxxm23/</link>
   <description>Using modeling for XML development (4 parts).</description>
  </item>
 </channel>
</rss>

XSLTの例

リスト3は、XSLTスタイルシートです。これはRSSドキュメントをHTMLで発行します。このスタイルシートは、リスト2内にあるすべての要素のテンプレート(xsl:template)を含み、XSLTプロセッサーに依存して最も適切なテンプレートを選択します。このスタイルシートはドキュメント全体を処理することを前提としていることがわかります。XSLTは要素が混在していてもうまく行きます。

リスト3.XSLTスタイルシート
<?xml version="1.0"?>
<xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
   <xsl:output method="html"/>
   <xsl:template match="rss">
      <html>
         <head><title>
            <xsl:value-of select="channel/title"/>
         </title></head>
         <xsl:apply-templates/>
      </html>
   </xsl:template>
   <xsl:template match="channel/title">
      <h1><a href="{../link}"><xsl:apply-templates/></a></h1>
   </xsl:template>
   <xsl:template match="title">
      <h2><a href="{../link}"><xsl:apply-templates/></a></h2>
   </xsl:template>
   <xsl:template match="description">
      <p><xsl:apply-templates/></p>
   </xsl:template>
   <xsl:template match="pubDate | link | language"/>
</xsl:stylesheet>

宣言方法に注目してください。何をするかは利用者が要素で指定し、テンプレートをいつ適用するかはプロセッサーが(組み込みのツリー・ウォーキング・ロジックによって)決めます。テンプレートの追加と削除は簡単です。プロセッサーは、ドキュメント内をどのようにして歩くかを知っているので、コードにはループは含まれていません。

XQueryの例

リスト4は、XQueryの例です。これは2つのクエリーを実行します。1つは、金曜日に発行された記事のリストを抽出し、もう1つは、XMIについて書かれた記事をリストします。

リスト4.XQuery
<result>
 {
  for $i in doc("rss.xml")/rss/channel/item
  where starts-with($i/pubDate/text(),"Fri")
  return
    <friday>
      { $i/title/text() }
    </friday>
 }
 {
  for $i in doc("rss.xml")/rss/channel/item
  where contains($i/title/text(),"XMI")
  return
    <xmi>
      { $i/title/text() }
    </xmi>
 }
</result>

リスト4リスト3を比較してください。XQueryでは、コードはXPathに依存して、対象となる要素を直接ポイントし、ループは明示的に書かれなければなりません。これは、ドキュメントからレポートを抽出するのに理想的です。

決定のとき

私はXPath 2.0の方言として、XSLT 2.0とXQuery 1.0を使い始めています。それぞれの方言は、特定のアプリケーション向けに最適化されています。両方の方言が普及するかどうかは、時間が経ってみなければわかりません。当分、私はXPath 2.0に努力を集中し、当面のアプリケーションに応じて最適な方言を使用してみるつもりです。


ダウンロード可能なリソース


関連トピック

  • Michael Kayによる「XSLTはどのような言語か」:XSLTの背景を知る:どこから来た言語なのか、何に適しているのか、なぜ使うべきなのかについて学んでください(developerWorks、2005年4月)。
  • Influences on the design of XQuery:XQueryのパイオニアであるDon Chamberlinによる記事で、XQuery言語の登場(XMLデータ用の照会言語に対するニーズと基本原理)について読んでください(developerWorks、2003年9月)。
  • Kevin Williamsによる「データ用のXML:XQueryの紹介」:XQueryの中核でFLWR(「flower」)句を使用する方法を学んでください(developerWorks、2002年2月)。
  • How an XSLT processor works:Benoit Marchalとともに、XSLTをユニークなものにしているツリー・ウォーキング・ロジックをこの記事で調べましょう(developerWorks、2004年3月)。
  • develperWorks XML ゾーン:記事とチュートリアルでXMLスキルを広げてください。
  • IBM XML certification:XMLおよび関連技術においてIBM認証開発者になる方法については、こちらを参照してください。
  • Saxon:SaxonでXSLTとXQuery処理を結び付けてください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=242787
ArticleTitle=実用的なXML:XSLT 2.0とXQueryの比較
publish-date=04042006