

JavaのXPathとは?
XPathとは、XML文書の特定の部分をパスで指定する方法です。
パスを利用して、必要な情報がどこにあるのかを表すため、 パスを入力とした抽出処理を考えられるようになります。
XPath自身はXML文書というわけではなく、XML文書の一部分として働きます。
XPathのデータモデルの場合、XMLデータを下記の7種類のノードで構成したツリーと考えます。
- ルートノード:最上位ノード
- 要素ノード:XML の要素を表すノード
- テキストノード:開始タグと終了タグで挟まれた文字列データ
- 属性ノード:要素内で指定された属性を表すノード
- 名前空間ノード:名前空間 (Namespace) を表すノード ※1
- 処理命令ノード:処理命令 (Processing Instruction) を表すノード
- コメントノード:コメントを表すノード ※ただし、ドキュメント型宣言内に記述するコメントを除きます。
※1 処理命令とは、「 <?」 と 「?>」 で挟まれた一文を指します。XML宣言は処理命令の形をしていますが、XML 1.0 の構文上、処理命令ではないことからXML宣言は処理命令ノードとしては扱いません。
基本的には、UNIX系の階層型ファイル・システムのパスと同様に指定可能です。
加えて、関数や式を組み合わせて複雑な指定もできるようになっています。
evaluateメソッドとは?
evaluateメソッドは、コンテキストでXPath式を評価して、結果をStringとして返すXPathのメソッドです。
使い方には4種類あり、それぞれ下記の通りとなっています。
修飾子と型 | メソッドと説明 |
---|---|
String | evaluate(String expression, InputSource source) 指定されたInputSourceのコンテキストでXPath式を評価し、結果をStringとして返します。 |
Object | evaluate(String expression, InputSource source, QName returnType) 指定されたInputSourceのコンテキストでXPath式を評価し、結果を指定された型として返します。 |
String | evaluate(String expression, Object item) 指定されたコンテキストでXPath式を評価し、結果をStringとして返します。 |
Object | evaluate(String expression, Object item, QName returnType) 指定されたコンテキストでXPath式を評価し、結果を指定された型として返します。 |
また、XPath式の評価は下記の通りです。
XPath式の評価 | |
---|---|
コンテキスト | コンテキスト項目がない式を評価する要求が行われた場合、コンテキストには空の ドキュメント・ノードが使用される。XPath式を評価するため、DocumentFragmentが ドキュメント・ノードと同様に扱われる。 |
変数 | 式に変数の参照が含まれる場合、setXPathVariableResolver(XPathVariable Resolver resolver)で設定されたXPathVariableResolverによってその値が見つけられる。 変数リゾルバが定義されていないか、リゾルバから変数に対してnullが返された場合、XPathExpressionExceptionが生成される。 変数の値は、1回の評価の過程を通じて不変でなければならない。 |
関数 | 式に関数の参照が含まれる場合、setXPathFunctionResolver(XPathFunction Resolver resolver)で設定されたXPathFunctionResolverによって関数が見つけられる。 関数リゾルバが定義されていないか、関数リゾルバから関数に対してnullが返された場合、 XPathExpressionExceptionが生成される。 |
QName | 式の中のQNameはsetNamespaceContext(Name spaceContext nsContext)で 設定されたXPath名前空間コンテキストと照らして解決される。 |
結果 | 式の評価の結果は目的の戻り値の型のインスタンスに変換される。 有効な戻り値の型は、XPathConstantsに定義する。戻り値の型への変換はXPath変換規則に従う。 |
参照:XPath (Java Platform SE 8 )
XPathの使い方(ロケーションパス)
XPathでXML文書のノードを指定するものを「ロケーションパス」と言います。
ロケーションパスは、スラッシュで区切ることでノード階層を表すものです。
ロケーションパスは、ルートノードから指定する”絶対ロケーションパス”と、任意のノードを起点とする”相対ロケーションパス”の2つがあります。
そして、起点とするノードのことをコンテキスト(文脈)ノードと言い、絶対ロケーションパスは、コンテキストノードがルートノードであるロケーション・パスです。
例えば、次のXML文書を参考にロケーションパスを記述してみます。
- <?xml version="1.0" encoding="UTF-8"?>
- <member>
- <user id="P210401" sex="male">
- <name>田中 太郎</name>
- <contact kind="email">tanaka@potepan.com</contact>
- <contact kind="url">https://style.potepan.com/tanaka</contact>
- <image file="tanaka01.png" />
- </user>
- <user id="P210401" sex="female">
- <name>佐藤 花</name>
- <contact kind="email">satou@potepan.com</contact>
- <contact kind="url">https://style.potepan.com/satou</contact>
- <image file="satou03.png" />
- </user>
- <user id="P210401" sex="male">
- <name>鈴木 裕斗</name>
- <contact kind="email">suzuki@potepan.com</contact>
- <contact kind="url">https://style.potepan.com/suzuki</contact>
- <image file="suzuki05.png" />
- </user>
- </member>
user要素配下のname要素を示すために、絶対ロケーションパスは次のように記述できます。
- /member/user/name
上記の絶対ロケーションパスの結果でマッチするのは、3つのname要素ですね。
また、ルートとそのすべての子孫ノードのname要素にマッチさせるためには、下記のように記述もできます。
- //name


XPathを取得する
JavaでXPathから要素を取得するサンプルです。
- ■記述例
- public void GetXpath(String xmlPath,String xpathStr) {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- try {
- DocumentBuilder db = dbf.newDocumentBuilder();
- Document doc = db.parse(new File(xmlPath));
- XPath xpath = XPathFactory.newInstance().newXPath();
- NodeList nl = (NodeList)xpath.evaluate(xpathStr, doc, XPathConstants.NODESET);
- int num = nl.getLength();
- for(int i=0;i<num;i++) {
- Node node1 = nl.item(i);
- NodeList nl2 = node1.getChildNodes();
- int num2 = nl2.getLength();
- for(int j=0;j<num2;j++) {
- Node node2 = nl2.item(j);
- if(node2.getNodeType() == Node.TEXT_NODE) {
- System.out.println(node2.getTextContent());
- }
- }
- }
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (XPathExpressionException e) {
- e.printStackTrace();
- }
- }
また、その他XMLに関する情報は、以下の記事でも詳しく解説しています。
ぜひ参考にしてみてください。
【関連記事】