IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  XML  >

XML の読み書きを単純化する

XPath などのクエリー定義によって DOM コーディングを大幅に単純化する

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

原文はこちら

原文はこちら


レベル: 初級

Cameron Laird (Cameron@Lairds.com), Vice President, Phaseit, Inc.

2007年 4月 03日

それほど複雑ではない XML を扱うアプリケーションであっても、XPath によって大幅にアプリケーションを単純化し、高速化することができます。まだ皆さんのツールキットの中に XPath が含まれていなかったら、今こそ XPath を追加すべきです。単純な Python でコーディングされた具体的な例を見ると、クエリー・イディオムの魅力が明確にわかります。

XPath は手元に置く価値のあるツールです。

もし皆さんが XML のプログラミングを稀にしか行わないとしても、まだ XPath を使っていないとしたら、皆さんのアプリケーションのパフォーマンスと保守性を何倍にも高められる可能性があります。この記事ではいくつかの具体的な例を示しながら、ごく単純な XML 処理であってもクエリーの方法によって大きな違いが生じることを説明します。

基本事項

XPath をスムーズに学ぶために、以下の基本事項を考慮しておく必要があります。

  • 以下の例は Python でコーディングされています。
  • おそらく皆さんはこれまで何度も、「X ...」が便利だと言われたことがあるでしょう。「X ...」は具体的な実際の問題を解決するために設計され、多くの委員会がそれに合意し、というような話です。実際私も、そうした話を何度も聞いています。ただし XPath は XML の世界の他の「X ...」のどれとも異なり、本当に役に立ちます。XPath は実際に作業するプログラマーが学ぶべき XML 定義として、XML そのものと XHTML に次ぐ、最も価値あるものなのです。
  • 皆さんには XPath が「必要」なわけではありません。皆さんは実際に作業する XML プログラマーであり、皆さんのアプリケーションには、必要な機能が既にあります。ただしポイントは、通常の手続き型プログラミングは XML の一般的な問題にあまり向いていないということです。たとえプログラムが既に正しく動作している場合であっても、クエリーのコーディングを少し改善するだけで、プログラムを読みやすく、保守しやすく、そして多くの場合、より高速に、時には大幅に高速化することができます。目標は、既に適切に動作しているプログラミングを捨て去ることではなく、即座に成果が得られる、補完的な方法を学ぶことです。

developerWorks の XML ゾーンの読者の大部分は、主に C、C++、あるいは Java で作業を行っています。ただし Python も、整理された擬似コードのように読むことができ、しかも簡単に入手できるため、解説するのにも適切な言語です。Python の初心者であっても、これから先の説明は簡単に理解できるはずです。

Python も他の多くの言語と同様、XML 機能を持つライブラリーを豊富にサポートしています。これまでは、どのライブラリーから始めるべきか迷うほどでしたが、Python の 2.5 がリリースされたことによって、Fredrik Lundh による素晴らしい ElementTree モジュールが標準となりました。この記事の例では、このライブラリーを使います。このライブラリー自体は小さく、1.5.2 までの任意の Python リリースと合わせて使うことができます (「参考文献」で説明しています)。ElementTree が用意できれば、ここにあげる例を実行するために必要なものがすべて揃ったことになります。




上に戻る


XML のプログラミング・モデル

現在見られる XML プログラミングの大部分は、DOM (Document Object Model) をベースとしています。この方式では XML インスタンスを要素のツリーとみなし、各要素はタグによって識別され、また多くの要素には属性やサブ要素があります。XML プログラミングは骨の折れる作業です。何よりも、XML 処理はツリーに従って各要素までナビゲートする必要があるからです。例えば、developerWorks の記事のコンテンツを作成するために developerWorks で使用されているテンプレート XML を考えてみます。この XML は XHTML とほとんど同じように見えます。この XML のスキーマは、(機械取引や金融取引に関する何千もの詳細を保存する) 産業アプリケーションに一般的な XML インスタンスと比べれば、明らかに単純で浅いものです。しかし、この単純なモデルでさえ、例えばテキスト中のすべてのアンカー・タグ (<a> タグの付いた全要素) に関するレポートが必要な場合には、基本的に任意の深さでネストされている文書の隅々までナビゲートしなければなりません。非再帰型のプロシージャー型の単純な式では、すべての要素にアクセスすることはできません (ただし多くのライブラリーにはツリーをウォークするためのヘルパー関数が含まれています)。

そのため、すべてのアンカーをレポートする単純なプログラムは、次のようなものになります。



リスト 1. すべてのアンカーをレポートする DOM ベースのコード
                
import elementtree.ElementTree
    
    def detail_anchor(element):
        if element.tag == "a":
            attributes = element.attrib
            if "href" in attributes.keys():
                print "'%s' is at URL '%s'." % (element.text,
                                                attributes['href'])
            if "name" in attributes.keys():
                print "'%s' anchors '%s'." % (element.text,
                                                attributes['name'])
    
    def report(element):
        detail_anchor(element)
        for x in element.getchildren():
            report(x)
    
    report(elementtree.ElementTree.parse("draft2.xml").getroot())
  

下記で説明する 5.5.1 基準テンプレートによって、このリストは次のような出力を作成します。


リスト 2. リスト 1 のプログラムからのレポート出力
                
'related developerWorks content' is at 'http://www.ibm.com/developerworks'.
    'entire series' is at 'http://www.ibm.com/...'
       ...

    'IBM product evaluation versions' is at 'http://www.ibm.com/...'
   


もし、DOM インスタンスに対してクエリーを実行するための標準的な方法や、指定された要素や属性、タグに関する情報のみを正確に抽出するための標準的な方法があったら、どれほど単純になることでしょう。下記を見てください。


リスト 3. リスト 1 と等価な、XPath ベースのコード
                


    import elementtree.ElementTree
    
    def detail_anchor(element):
        if element.tag == "a":
            attributes = element.attrib
            if "href" in attributes.keys():
                print "'%s' is at URL '%s'." % (element.text,
                                                attributes['href'])
            if "name" in attributes.keys():
                print "'%s' anchors '%s'." % (element.text,
                                                attributes['name'])
    
    for element in \
           elementtree.ElementTree.parse("draft2.xml").findall("//a"):
        detail_anchor(element)
   

"//a" の意味が、「文書全体の中で ‘a’ というタグの付いたすべての要素を検索する」であることに注目してください。リスト 3 の出力は、基本的にリスト 2 と同じです。

ElementTree のインストール

ElementTree を使った、皆さん独自の Python をインストールしてください。単純にコード・リストを読むだけでも結構ですが、皆さん自身でコードを実行した方が、さらには皆さん自身のアイデアでコードを変更して実験してみた方が、ずっと楽しいはずです。

それは難しいことではありません。これまで私が出会った多くの XML ツールキットの面倒さとは対照的に、ElementTree をインストールして使い始めるには数分しかかからないはずです。

まず、Python そのものが必要です。最近の大部分の UNIX ディストリビューションは (MacOS やほとんどすべての Linux のバリエーションを含め)、Python を組み込んであります。Windows に関しては、「参考文献」にあげた ActivePython を参照してください。

Python が用意できたら、

  1. elementtree ソース・バンドルを入手します (「参考文献」に記載されているように、ElementTree のホームから入手できます)。
  2. このソース・バンドルを解凍します。
  3. 適当なディレクトリー (おそらく、elementtree-1.2.6-20050316/ のようなディレクトリー、要は setup.py がある場所です) までナビゲートします。
  4. コマンド・ラインから、python setup.py install と呼び出します。

これだけで終わりです。インストールを確認するためには、対話型の Python シェルを起動し、そして import elementtree.ElementTree をリクエストします。

リスト 13 とを比較してみてください。確かに前者は十分単純ですが、後者はさらに単純です。後者は、再帰を明示的に指定する必要がありません。さらに重要な点として、XPath は XML の構造に対してではなく、XML の (論理的な) マークアップに対してコーディングされています。マークアップの方が人間の考え方に近く、そして長く持続されます (つまりこの観点から見ると、構造は比較的寿命の短い、実装の詳細にすぎません)。もっと複雑なクエリーの場合には、構造指向でプロシージャー型の典型的な検索実装よりも、XPath の宣言型スタイルの方が明らかに優れています。

この記事のポイントは、既存の XML プログラム開発の中に XPath を採り入れ、それによってパフォーマンスと保守性を即座に改善できるということです。これは私にとっては、アセンブラーやコンパイラー、そして高位言語を使うようなものです。つまり私はプログラム全体をマシン語で作成することができ、作成してきましたが、より生産性の高い方法を学んでおくことは、単純に賢明なことなのです。しかも、XPath を使った方が、多くの場合はハンド・コーディングによる検索よりもパフォーマンスを改善することができます。

ただしこれによって疑問が提起されます。XPath を改善する方法はあるのでしょうか。もちろんありますが、制限付きです。XQuery と XSLT とは、XPath よりも広く受け入れられている 2 つの XML 定義です (おそらく XSLT が 3 つの中で最も広く使われており、また便利な実装が最も少ないのは XQuery です)。XSLT は宣言型を強調している点で XPath と似ており、一方 XQuery は XPath のクエリー動作に手続き型の機能を追加します。どちらを使った場合もテンプレート動作 (大まかに言えば認識可能な XML フラグメントを埋め込むクエリー) は多少イディオム風になります。この点は、何人かの XML 理論家がテンプレート動作を望ましい表現形式として推奨していることから、注目に値します。

しかし全体としては、XQuery や XSLT、あるいは Amara や XQJ、JAXP など言語専用のクエリー・パッケージなどによる利点は、私が XPath に関して主張する大きな見返りに比べれば、わずかなものです。「参考文献」にあげた Uche Ogbuji による論文では、問題の例をいくつかの異なる方法で解決した場合が比較されています。こうした、より特化したインターフェースは、XML 処理があまりにも複雑と思われる場合にのみ使用すべきものです。しかし XPath は、今すぐに使い始められるのです。




上に戻る


他の例

この記事の目的は、XPath を教えることではなく、XPath を使ってみる気になってもらうことです。XPath はほとんど手間をかけずに学び始められることを、この記事からはっきりと理解して欲しいと思います。

また皆さんは、XPath を使うことで、どれだけのことができるかも知りたいかもしれません。リスト 3 のクエリーには、単純な例として //a があります。皆さんはやがて、/parent/child[@attr='value'] のような、もっと複雑なクエリーについて学ぶでしょう。このクエリーはすべての “child” ノードを指定しています (“child” ノードは “parent” の子であり、”value” という値の属性 “attr” を持ちます)。さらに 2 つの例をあげると、//@* はすべてのタグのすべての属性を検証し、また //tr/td|th は tr の中にあるすべての td 要素あるいは th 要素を取得します。




上に戻る


パフォーマンス

パフォーマンスについて検討する場合は、必ず特定の測定項目に絞って考える必要がありますが、XPath のパフォーマンスを有効に評価するためには少し配慮が必要です。乱暴な言い方をするなら、XPath は皆さんよりも高速です。パフォーマンスが問題となる大規模で複雑なプログラムでは、XPath クエリーは多くの場合、ハンド・コーディングによる手続き型のコードよりも高速 (場合によるとずっと高速) です。原理的には、データの内容あるいは配置に関する知識を使えば、非常に高速で賢い探索が可能なコードを作成できるかもしれません。しかし実際には、XPath によって起こることは、アセンブラーあるいは C を使わずに、高級言語 (HLL) を使った場合に起こることと似ています。つまり開発者は適切に動作するプログラムをずっと少ない労力で完成させることができ、HLL は本質的にスピードの面で不利という表面的な欠点は、優れたアプリケーション専用アルゴリズムによって容易に補えるのです。

それと同様に、大きな問題の場合 (スピードが問題となるため、プログラマーは多少の余裕を持って慎重にソリューションを作成することができます) にも、XPath によってコーディングを単純化することができます。XPath ベースのソリューションは、結局のところ修正や保守をしやすいばかりではなく、なんといっても高速なのです。

さらに、一部の XPath 実装は、初歩的なプロシージャー型検索よりもメモリーを効率的に利用できるように、注意深く作成されています。こうした場合では、XPath ベースのコーディングは検索を何倍も (10 倍あるいはそれ以上) 高速化することができます。

こうしたポイントを実証する特定の測定結果を示せないことは苛立たしいものです。ただし、どのような具体的な比較を行った場合も、誤解を生じる可能性があります。つまり XPath が他と比較して優れたパフォーマンスを発揮するかどうかは、開発言語や、特定の XPath 実装、照会される XML イメージ、検索方法、そして多くの場合、利用可能なランタイム・メモリーのレイアウトなどに依存します。まず単純なタイミング測定を行うための方法を学び、そしてアプリケーションにとって標準的なデータセットに対して XPath をテストしてみてください。もし私の経験と同じような結果が得られるとしたら、特に小さな問題の場合には、普通にコーディングした場合の半分程度の速さのこともあるかもしれませんが、そうした問題以外では他のソリューションよりも 1 桁も違うほど高速なことに気が付くはずです。




上に戻る


まとめ

XPath は、ほとんど苦労なく使い始められる XML 機能です。皆さんが使用する開発言語の XML ライブラリーの中には、既に XPath が組み込まれているかもしれません。また同時に、XPath によって大幅にパフォーマンスを改善できる可能性もある上、XPath の単純な表現力のため、プログラミングや保守を確実に単純化することができます。また、必要なことを学ぶための XPath チュートリアルも豊富にあります。つまり XPath への投資は、すぐに回収できるのです。

XPath を知ることによって、XML に関する作業について、要求が厳しく、XQuery や XSLT のような高度なツールを使用した方が有益であるのかどうかを、正確に判断できるようになります。

「参考文献」にあげた資料を必ず読み、皆さん自身が XPath のプログラミングを始めるために役立ててください。



参考文献

学ぶために
  • developerWorks の「魅力的な Python」シリーズを読んでください。なぜ XPath を説明するために Python を使うのでしょうか。David Mertz による、このコラムでは、Python 言語の利点の詳細を解説しています。Python を使う最も単純な理由として、Python はごく容易に入手できること、また Python を知らないプログラマーであっても通常は Python で作成されたプログラムを容易に読むことができることがあげられます。

  • ActivePython を調べてみてください。このホームページによると、ActivePython は品質の保証されたインストール可能な Python ディストリビューションです。著者は特に、インストールの信頼性の点から、Python に関心を持つ Windows ユーザーに ActivePython を推奨します。

  • ElementTree のホームページを見てください。Fredrik Lundh によって作成、維持管理されている ElementTree ラッパーは、XML ファイルを Element オブジェクトのツリーとしてロードし、保存するコードを追加します。ElementTree には、上記の囲み記事で説明している単純なインストールの他に、他のライブラリーを活用したりパフォーマンスを改善したりするための、さまざまな実装が付属しています。

  • Get started with XPath」(Bertrand Portier 著、developerWorks、2004年5月) では、XPath とは何か、XPath 言語の構文とセマンティクス、XPath のロケーション・パスの使い方、XPath 式の使い方、XPath 関数の使い方、XPath と XSLT との関係などを学ぶことができます。このチュートリアルは XPath Version 1.0 をカバーしています。

  • XPath tutorial」(Miloslav Nic と Jiri Jirat, zvon の共著) では、より抜きの XPath 機能を、豊富な例と共に学ぶことができます。

  • W3C が管理する仕様、XML Path Language (XPath)specification を読んでください。XSLT (XSL Transformations) と XPointer と共通な機能に関する一般的な構文やセマンティクスを学ぶことができます。

  • XPath as data binding tool, Part 2」(Brett McLaughlin 著、developerWorks、2006年1月) は、JAXP API を使って XPath クエリーを行い、XPath を使って Java でコーディングしています。

  • XGrep は XML 文書に対する、grep のようなユーティリティーです。」 XGrep は開発者が常に手元に置くべき素晴らしいツールです。この記事は Python を使った例をとおして XML プログラミングを説明しています。ただし、もし著者 Cameron が XPath を使ってプログラムを作成する方法よりも XPath 自体を強調するとしたら、著者は、むしろ XGrep の観点から説明しているのだと思います。

  • XQuery 入門」(Howard Katz 著、2006年1月更新) では、XML クエリー言語に関して W3C で提案されている標準を解説しています。

  • XSLTはどのような言語か」(Michael Kay 著、2005年4月) は XSLT に関して、その起源、XSLT が得意なこと、なぜ XSLT を使うのか、などについて解説しています。

  • Jonathan Robie は、この非常に興味深いインタビュー、「A conversation with Jonathan Robie about XQuery」の中で、XML クエリー言語に関して述べています。

  • Is XQuery an omni-tool?」の中で、Uche Ogbuji は特に XQuery に焦点を当てています。Ogbuji はこれらの会議ノートの中で、XPath と XSLT、そして XQuery との間の関係を解説しています。

  • developerWorks の XML ゾーンでは、XML のすべてを学ぶことができます。

  • XML および関連技術において IBM 認証開発者になる方法については、IBM XML certification を参照してください。

  • developerWorks の XML ゾーンは XML の技術ライブラリーとして、広範な話題を網羅した技術記事やヒント、チュートリアル、技術標準、IBM レッドブックなどを用意しています。

  • developerWorks technical events and webcasts で最新情報を入手してください。


製品や技術を入手するために
  • developerWorks から直接ダウンロードできる IBM trial software を使って皆さんの次期開発プロジェクトを構築してください。


議論するために
  • XML zone discussion forums に参加してください。これらのフォーラムでは XML を中心に議論が行われています。


著者について

Photo of Cameron Laird

Cameronは、Phaseit, Inc. の常勤のコンサルタントです。オープン・ソースなどの技術的なトピックについて、数々の執筆や発言を行っています。Cameronのメール・アドレスはclaird@phaseit.net です。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


    日本IBMについて プライバシー お問い合わせ