XMLマスターへの道
〜「XMLマスター:ベーシック」試験対策〜
第12回 XPathによるノードの指定法を理解する
内藤一彦NRIラーニングネットワーク株式会社
2003/12/23
前回「第11回 XSLTで必須の制御命令を覚える」、前々回「第10回 XSLTの基本構造を理解する」と2回にわたりXML文書の変換を行うためのXSLTの利用方法について紹介しました。今回は、XSLTと密接な関係にあるXPathについて紹介します。前回に予習問題として下記の問題を出題しておきました。この問題を解くための解説をした後、解答を示します。
今回の問題 | ||||
|
||||
(Q1) 共通のXMLからSalaryが400000以上の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
|
||||
(Q2) 共通のXMLのEMPLOYEEのうち、先頭の2件(データの記述順)の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
|
今回は、この問題に解答するうえで必要となる下記の内容について解説します。
- XPathの概要
- XPathのデータモデル
- ノードの種類
- ロケーションパス
- ロケーションパスの記述方法
- ノードテスト
- 条件式
■XPathの概要
XPathとは、XML関連の規格の1つでXSLT version 1.0と同時期に標準仕様として勧告されています(W3C仕様原文)。XPathを使用すると、XMLドキュメント中のノードをアドレッシング(XMLドキュメント中のある場所を指し示して、その場所にアクセスする)できるようになります。また、XPath関数と呼ばれる30ほどの便利な関数が用意されています。
XPathのノード・アドレッシング機能はいろいろな場面で利用されています。代表的なものはXSLTとの関係で、おそらくXSLTはXPathなしでは使えないといえます。例えばXSLTで要素や属性の値を取得したいときに、次のように記述しました(第10回 XSLTの基本構造を理解する XSLTの基本構造)。
xsl:value-of select ="@empid" |
また、ある要素をテンプレートで処理したい場合、次のように記述しました。
xsl:apply-templates select="/EMPLOYEES/EMPLOYEE" |
実は、どちらのselect属性も、指定するのはXPathに基づく式なのです。ほかにも、xsl:templateのmatch属性、xsl:for-eachのselect属性……などさまざまな個所で使用します。
また、XPathをサポートしているリレーショナルデータベース製品では、データベース中のデータをXPathを使って検索できるものもあります(参考「XMLデータベース製品カタログ 2003」)。
ノードの種類
XPathでは、XMLドキュメント中にある要素や属性などをノードとして、ツリー構造にモデリングして操作します。XPathのノードの種類には次のものがあります。
ノードの種類 | XMLドキュメント内の対応 |
ルートノード | XMLドキュメントで一番トップレベルのノード(ルート要素ではない) |
要素ノード | 要素 |
属性ノード | 属性 |
テキストノード | 要素の値 |
名前空間ノード | 名前空間 |
処理命令ノード | 処理命令 |
コメントノード | コメント |
この中で、ルートノード、テキストノードに注意が必要です。ルートノードはXMLドキュメントで最上位に位置し、ほかのすべてのノードはこの子孫に含まれることなります(ルート要素は、このルートノードの子ノードです)。テキストノードは要素の値です。XPathでは、「要素の値」は要素ノードが持っているのではなく、「テキストノード」が持つことになっています。
下記にXMLドキュメントの例を挙げますので、ノードの種類を整理しましょう。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト1 XML文書(datamodel.xml) |
このXMLドキュメントに含まれている各ノードのツリー構造は次のようになります。
図1 datamodel.xmlのツリー構造 |
この階層構造で注意すべきノードは、属性ノードです。属性ノードは特別な扱いを受けており、要素ノードの子どもには含まれません(属性ノードの親は要素ノードですが)。ですから、EMPLOYEE要素ノードのすべての子ノードを取得しようとしても、empid属性ノードは含まれません。
リスト1のXML(datamodel.xml)に次のようなXSLT変換を適用します。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト2 XSLT文書(datamodel.xsl) |
このXSLTでは、ルートノード以外の各ノードの名前と値(xsl:value-of)を取得します。XMLファイルをIEで開くと次のような表示結果が得られます。
図2 IEによる変換結果の確認(datamodel.xml) |
表示内容は、ノードごとに「ノードの名前:::xsl:value-ofの結果」となっています。コメントノードやテキストノードは、要素ノードや属性ノードと異なり、ノード名を持たない特別なノードです。
■ロケーションパス
ロケーションパスの記述方法
ロケーションパスとは、ノードを指し示すための式です。XPathの機能の中で最も利用される機能でしょう。ロケーションパスの記述方法は、OSのディレクトリ階層と同じような書式を取り、階層構造はノード名とノード名を「/」で区切り記述します(ノード名/ノード名/ノード名)。また、絶対パス(ルートノードから階層構造を指定)と相対パス(現在の作業位置からの相対的指定)の2通りの記述ができます。
現在の作業位置がEMPLOYEE要素ノードだとすると、Name要素ノードを選択するのに次のような記述が行えます。
絶対パス: "/EMPLOYEES/EMPLOYEE/Name"
相対パス: "Name"
式の先頭が「/」(ルート)から始まっていれば絶対パスです。
ノードテスト
ノードテストとは、ノードの種類を評価する関数です。テキストノード用のノードテストはtext()で、そのノードがテキストノードであれば、「true」が結果として返ります。
ノードテストの種類 | trueが返るノードの種類 |
comment() | コメントノード |
text() | テキストノード |
processing-instruction() | 処理命令ノード |
node() | すべてのノード |
コメントノードやテキストノードはノード名を持たないので、これらのノードを指定したい場合には名前の代わりにノードテストを使います。以下に2つの例を挙げます。
/EMPLOYEE/EMPLOYEE/Name/text() | |
Name要素の値(Name要素ノードの子のテキストノード) |
|
/EMPLOYEE/EMPLOYEE/node() | |
EMPLOYEE要素のすべての子ノードが選択されます。ただし、属性ノードは含まれません。XPathデータモデルでは属性ノードは要素の子ノードではないためです。 |
ロケーションパス式の中で、ノードを選択するための条件式を付加できます。条件式は、ノード名に続けて[ ]内に記述します。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト3 サンプルXML文書(filter.xml) |
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト4 XSLT文書(filter.xsl) |
EMPLOYEE要素に対してテンプレートの呼び出しを行いますが、Salaryの値が400000以上という条件を設けています(式の中で「<」や「>」など特殊記号を使用する場合は注意してください)。
図3 IEによる変換結果の確認(filter.xml) |
ここで使用しているサンプルのXMLファイルとXSLTファイルは、前回予習問題として取り上げたものです。これが、前回の問題(Q1)の解答となります。
このサンプルでは、[ ]内にtrue/falseが返る条件式を記述していますが、数値(または数値を返す式)も記述できます。その場合、n番目の要素を指定します。
リスト3と同じ内容のXMLファイル(filter2.xml)に次のXSLTを適用してみます。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト5 XSLT文書(filter2.xsl) |
EMPLOYEE要素に対してテンプレートの呼び出しを行いますが、2番目のEMPLOYEEを指定しています。
図4 IEによる変換結果の確認(filter2.xml) |
n番目の指定には、このように[2]と記述する方法もありますが、XPath関数のposition関数を使って、[position()=2]と記述しても同様に2番目のノードが得られます。予習問題(Q2)にあるように、 position() < nや position() > nという書式を取れば、n番目より前(後ろ)という指定になります。リスト3と同じ内容のXMLファイル(filter3.xml)に次のXSLTを適用してみます。
<?xml version="1.0" encoding="Shift_JIS" ?> |
リスト6 XSLT文書(filter3.xsl) |
EMPLOYEE要素に対してテンプレートの呼び出しを行いますが、3番目より前のEMPLOYEEを指定しています。
図5 IEによる変換結果の確認(filter3.xml) |
参考
ノードに対する条件の指定は、ロケーションパスの途中のノードでも記述することができます。以下に例を挙げます。
/EMPLOYEES/EMPLOYEE[position()<3]/Name |
■今回の問題の解答
それでは、予習問題の解答です。
(Q1) 共通のXMLからSalaryが400000以上の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
答えは、(b)の/EMPLOYEES/EMPLOYEE[Salary>=400000]です。
「ロケーションパス(条件式)」で、この問題をサンプルに取り上げていますので、もう一度確認しておきましょう。
(Q2) 共通のXMLのEMPLOYEEのうち、先頭の2件(データの記述順)の社員情報を取得したい。共通のXSLTのテンプレートの(1)に入れるべき記述として正しいものを選択してください。
答えは、(c)の/EMPLOYEES/EMPLOYEE[position()<3]です。
n番目の指定で、「=」を使う場合、position関数を使って
[position()=2] |
と記述する代わりに、
[2] |
のような指定もできます。しかし、「<」「>」を使用する場合は、position関数が必要となります。
[position() <3] |
という指定は
[<3] |
とは記述できません。「ロケーションパス(条件式)」で、この問題をサンプルに取り上げていますので、もう一度確認しておきましょう。
■次回の予習問題
次回のために予習問題を掲載します。
次回は名前空間とDOMです。名前空間はXMLを活用するうえで何かと使用されている機能です。基本的な概念や宣言方法を紹介します。また、DOMはJavaなどのアプリケーションからXMLを操作するときに使用する標準のAPIです。詳しい内容は、XMLマスター・プロフェッショナルの範疇になりますが、次回はXMLマスター・ベーシックの範疇である基本的な内容を紹介します。
予習問題 | ||||||||
(Q1) 下記に示されるXMLインスタンスがあります。NAME要素のnickname属性が属する名前空間はどれでしょう。
|
||||||||
(Q2) DOMに関する説明として正しいものをすべて選んでください。 (a)DOMツリーと呼ばれるツリーを構築して各ノードにアクセスする |
■まとめノート:XPathによるノードの指定法を理解する
○今回の試験対策のポイント
- XPathの概要
- XPathのデータモデル
- ノードの種類
- ロケーションパス
- ロケーションパスの記述方法
- ノードテスト
- 条件式
○今回の学習内容で出題範囲となる仕様
○今回の学習内容で参考になる@ITの記事
- 技術者のためのXML再入門(8) XML文書内の位置を正確に指し示すXPath
- XSLTスタイルシート書き方講座 (2) XPathの書き方の基本
- XMLテクニック集
- サンプルで覚えるXSLTプログラミング(2) XPathの基礎知識
- VBScriptでXMLプログラミング(2) DOMを使って目的の情報へダッシュ
○今回の学習内容で参考になるXML用語集 (@IT XML用語事典より)
(13)名前空間を理解しDOMの概要をつかむ |
連載:XMLマスターへの道 |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|