Java XPATHで条件にマッチしたテキストを取得する。
2011年7月21日
xmlファイルから特定の文字列を取得する必要があったのでXPathというものを利用してみました。
XPathは標準ライブラリに含まれているので手軽に利用できます。(JDK5以降?)
XPathな便利なところは、UNIXのディレクトリ構造のように(/usr/bin/とか)Pathを指定することで簡潔に対象ノードを取得することが可能です。
下記にXMLのサンプル・コーディング例を記載します。
[XMLサンプル(sample.xml)]
<books>
<book id="1">
<title>Javaブック</title>
<author>田中一郎</author>
<price>1800円</price>
</book>
<book id="2">
<title>effectiveJava</title>
<author>鈴木二郎</author>
<price>2000円</price>
</book>
<book id="3">
<title>日経</title>
<author>佐藤三郎</author>
<price>3500円</price>
</book>
</books>
[XML,コーディングサンプル]
String filePath = "./sample.xml";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(filePath));
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
XPathExpression xpe1 = xp.compile("/books/book[attribute::id=\"1\"]/title/text()");
XPathExpression xpe2 = xp.compile("/books/book/title[parent::node()[attribute::id=\"1\"]]/text()");
String s1 = (String)xpe1.evaluate(doc, XPathConstants.STRING);
System.out.println("title="+s1);
String s2 = (String)xpe1.evaluate(doc, XPathConstants.STRING);
System.out.println("title="+s2);
実行結果は
title=Javaブック
title=Javaブック
となります。
通常はxpe1のように書くのが普通ですがxpe2のように指定しても最終的に同じnodeを見るので結果は同じです。
bookの中から"Javaブック"の値段(price)が知りたい場合には
XPathExpression xpe3 = xp.compile("/books/book/title[text()=\"Javaブック\"]/../price/text()");
のように記述すればprice(1800円)が取得できます。(title("Javaブック")ノードから".."で親ノードに戻ってpriceノードを取得している)
大事なのは、指定したXpathExpressionで自分がどの位置(node)にいるのかをちゃんと把握することだと思います。
後は軸(ノードから次のノードを探す方向(self,attribute,child等)の表現や述部([]で囲まれてる箇所)で条件を絞って目的のノードを取り出すだけです。
軸にどのような種類があって、どのような述部の指定で条件を絞れるのかがわかれば割と手軽に扱えると思います。
参考サイト:
よく拝見している倭マンさんのサイトが視覚的に説明してあってわかりやすかった。