この付録では、RUEI内部で用意されている、XPath問合せを使用するためのサポートについて詳しく説明します。
XPath(XML Path言語)は、XML文書のデータの問合せに使用できる問合せ言語です。RUEIでは、XPath問合せを使用して、XML文書のコンテンツをスキャンできます。XPathの完全な仕様は、http://www.w3.org/TR/xpath
を参照してください。XPathは、XML文書のツリー表現に基づき、様々な基準によってノードを選択します。一般に、XPath式は単にXPathと呼ばれるのが通例です。
RUEIでは、XPath式のサブセットを使用して、ページ名やWebサービスを検索したり、ページ・コンテンツや関数エラー・チェックを実行できます。必要に応じて、見つかった要素内のリテラル文字列も検索するように、検索を拡張できます。
XPath式では大/小文字が区別されることに注意してください。
次のような単純なXML文書について考えます。つまり、ルート要素が<a>
で、このルート要素に1つの子要素<b>
があり、さらにこの子要素に2つの子要素<c>
および<d>
が含まれるXML文書です。
<?xml version="1.0" encoding="UTF-8"?><a> <b> <c>Hello world!</c> <d price="$56" /> </b></a>
XPath問合せでは、親子関係は/
(スラッシュ)で示され、要素名は山カッコ(<
および>
)なしで記述されます。つまり、a/b
は、<a>
要素の子である<b>
要素を選択することを意味します。問合せの最初の/
は、パスの最初のノードがドキュメントのルート要素であることを示します。たとえば、次の問合せでは、ルート要素<a>
の子である<b>
要素の子の<c>
要素を選択します。
/a/b/c
この問合せをコンテンツのスキャンに使用すると、前述のサンプル・ドキュメントからHello world!というテキストが抽出されます。別の例として、問合せ/html/body/div/p
を使用すると、XHTMLドキュメントの本文にある<div>
内の全段落のコンテンツが抽出されます。
要素のコンテンツ以外にも、抽出できるタイプのデータとして、XML属性値があります。属性を問い合せるには、要素の属性であるそれらの属性を、要素の子として参照します。属性名と要素名を区別するには、属性名の前に@
文字を付加する必要があります。@属性ノードは、XPathの最後のノードとしてのみ使用できます。たとえば、次の問合せを使用すると、前述のサンプル・ドキュメントから$56というテキストが抽出されます。
/a/b/d/@price
RUEIでサポートされているXPath構文は、簡略式のXPath構文のサブセットです。そのため、他のXPathアプリケーションでは正しく動作する構文要素がRUEIでは動作しない場合があります。たとえば、次の問合せは許容されません。
//c # error, // not supported/a/*/b # error, * not supported/a/b/c/../b # error, . and .. not supported
また、まったく問題のない次のような問合せにおいても、前述のサンプル・ドキュメントからは何も抽出されません。
/a/c # no <c> elements are children of the <a> element/b/c # <b> is not the root element/a/b/e # the document does not have <e> elements
要素名と属性名では大/小文字が区別されます。つまり、/a/b/c
は/A/B/C
と同じではありません。
RUEIでは、すべてのXPath問合せは絶対パスで記述する必要があります。つまり、ルート・ノードで始まるとともに、パスに沿って各子要素の名前が明示的に指定されている必要があります。
次の少し複雑なXML文書について考えます。
<?xml version="1.0" encoding="UTF-8"?><inventory> <item class="food"> <name>Bread</name> <amount>12</amount> </item> <other> <msg>not available</msg> </other> <item class="cleaning"> <name>Soap</name> <amount>33</amount> </item> <item class="food" type="perishable"> <name>Milk</name> <amount>56</amount> </item></inventory>
ルート要素<inventory>
には、<item>
という子が3つと<other>
という子が1つ含まれます。次のように、XPath問合せのノードでインデックス[N]
を使用することで、明示的にN番目の<item>
子要素を選択できます(0ではなく1からカウントを開始)。
/inventory/item[2]/name # extracts "Soap"
前述のサンプル・ドキュメントを使用する場合、<name>
ノードでインデックスを指定しても意味はありません。このドキュメントには3つの<name>
要素が存在しますが、3つとも別の<item>
要素の子になっています。つまり、これらの要素はそれぞれ1番目の子になっています。
/inventory/item/name[2] # extracts nothing
属性条件は、選択する要素をより正確に指定するための別の方法です。属性条件には2つの形式があります。1つ目の形式[@attr="value"]
では、attr
属性に値が設定された要素のみが選択されます。もう1つの形式[@attr]
では、attr
属性を任意の値に設定できる要素のみが選択されます。
/inventory/item[@class="cleaning"]/name # extracts "Soap"/inventory/item[@type]/name # extracts "Milk"
and
キーワードを使用して、単一のノード内の複数の属性条件を結合できます。ただし、XPathキーワードor
はサポートされていません。また、二重引用符(")のかわりに一重引用符(')を使用して属性値を囲みます。
/inventory/item[@class='food' and @type]/name # extracts "Milk"
インデックスと属性条件は結合できます。次の2つの問合せの違いは、問合せAが最初にclass="food"
であるすべての<item>
要素を選択してから2番目の要素を取得するのに対し、問合せBはclass="food"
(ただし、例ではclass="cleaning"
)であるという条件で2番目の<item>
要素を選択することです。
A: /inventory/item[@class="food"][2]/name # extracts "Milk"B: /inventory/item[2][@class="food"]/name # extracts nothing
エラー値の抽出
次のXML-SOAPメッセージについて考えます。
<?xml version="1.0" ?><env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:xml="http://www.w3.org/XML/1998/namespace"> <env:Header> <env:Upgrade> <env:SupportedEnvelope qname="ns1:Envelope" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope"/> <env:SupportedEnvelope qname="ns2:Envelope" xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/"/> </env:Upgrade> </env:Header> <env:Body> <env:Fault> <env:Code> <env:Value>env:VersionMismatch</env:Value> </env:Code> <env:Reason> <env:Text xml:lang="en">Version Mismatch</env:Text> </env:Reason> </env:Fault> </env:Body></env:Envelope>
次のXPath問合せでは、エラー値env:VersionMismatch
を抽出できます。
/env:Envelope/env:Body/env:Fault/env:Code/env:Value
タグ属性の抽出
次のXMLコードについて考えます。
<html> <head lang="NL"> <meta http-equiv="BBL_HB_ERROR" content="E50/01/G009-210"> </head> <body> <h1>hello</h1> </body> </html>
次のXPath問合せでは、値E50/01/G009-210を抽出できます。
/html/head/meta[@http-equiv='BBL_HB_ERROR']/@content
XPath問合せをリアルタイムのHTTPデータ・ストリームに適用するため、RUEIではXPath 1.0機能の一部しかサポートされていません。具体的には、次のとおりです。
入力トラフィック内の内部ファイルと外部ファイル(DTDなど)の参照は無視されます。
self-or-descendant(//)演算子はサポートされていません。
XPath式の最大深度は16レベルです。
式内では、指定した文字列の単なる部分文字列を追加の文字列として指定することはできません。文字列の最大長は256バイトです。
また、次の点にも留意してください。
RUEIでは、トラフィックのコンテンツが実際にXML形式であるかどうかを問わず、すべてのトラフィックのコンテンツに対してXPath一致が適用されます。つまり、XHTMLは、サポートされているものの、整形式XMLとして解釈されます。そのため、非整形式XMLや非XMLトラフィックに対してXPath問合せを使用すると、結果の信頼性が損われる可能性があります。
名前空間とCDATAの使用はサポートされていません。これらが入力ストリームに存在する場合はリテラルとして扱われます。そのため、誤一致が生じる可能性があります。
すべての式はANDとして解決されます。ORと関係式(<=、>=、<、>など)の使用はサポートされていません。
利便性向上のため、Mozilla FirefoxのXPather拡張など、サード・パーティのXPathツールを使用して、RUEI内で使用可能なXPath式を作成できるようになっています。このXPather拡張は、http://xpath.alephzarro.com/index
から入手可能です。
インストールすると、ページ内で右クリックして「Show in XPather」オプションを選択できるようになります。例を図F-1に示します。
次に、XPatherブラウザ(図F-2を参照)内でXPath式をコピーすることで、それをRUEIでのXPath問合せのベースとして使用できます。必ず、生成されたXPath式を確認して、前述の制限事項に準拠していることを確認してください。