dom4jとXPathを使用して、XML文書から特定の要素を取出します。
dom4jは、XML 文書全体をメモリ上に展開して、任意のノードに好きなようにアクセスできる API を提供します。逆に、一度全データをメモリ上に展開するので、データ解析などで大量のデータを含むXMLファイルを読み込んで、処理するには向いてません。dom4jは、Welcome to dom4j 2.0!からダウンロードできます。現在の最新は2.0です。XML 文書の取得に関するクラスは、org.dom4j.DocumentHelperと org.dom4j.io パッケージ内のクラスです。
XPathとは、XML Path Langageの略で、XML文書の中の特定の要素を指し示す記述方法を定めた規格のことです。JavaでXPathを扱う場合は、XPathの評価エンジンであるjaxenライブラリを使います。今回は、jaxen-1.1.3を使用しました。
dom4jとXPathで特定の要素だけの取り出し
XPathの評価エンジンであるjaxenとdom4jを使えば、XPathの式を使って要素を取り出すことができます。次の例は、XMLのうちのnameがsho322のもののjobとageを取り出します。抽象的に言うと、XPathで特定のノードの兄弟ノードを取り出します。
まず、今回使用するXMLファイル「member.xml」を次に示します。
<?xml version="1.0" encoding="UTF-8" ?> <persons> <person> <name>sho322</name> <age>28</age> <job>programmer</job> </person> <person> <name>michitaka</name> <age>27</age> <job>kami</job> </person> <person> <name>toshi</name> <age>27</age> <job>ikemen</job> </person> </persons>
次に、Javaのプログラムを示します。dom4jによるSAXReader.read を用いた XML ファイルの読み込み。今回は”member.xml”を渡すと Document 型に変換できます。selectNodesメソッドは、XPath 式に合致する全てのノードをリストで返します。
public static void main(String[] args) {
SAXReader reader = new SAXReader();
try {
Document document = reader.read("C:\\tmp\\member.xml");
List nodes = document.selectNodes("/persons/person/name[text()='sho322']/following-sibling::*");
for(Iterator i = nodes.iterator(); i.hasNext();) {
Node node = (Node) i.next();
System.out.println(node.getText());
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
XPath式は、”/persons/person/name[text()=’sho322’]/following-sibling::*”となります。実行結果は次のようになります
28 programmer
XPath で使用できるメソッド
XPath 関連のメソッドをまとめると、次のようになります
| 名前 | 返り値 | 説明 |
|---|---|---|
| selectSingleNode(String) | Node | XPath 式に合致する最初のノードを返します。 |
| selectNodes(String) | List | XPath 式に合致する全てのノードをリストで返します。 |
| elements(String) | List | 子要素を List オブジェクトで返します。要素名をしてした場合は、その名前をもつ子要素のみ返します。 |
| nodeCount() | int | 子ノードの数を返します。 |
| asXML() | String | 属性配下の XML を文字列で返します。 |
| getText() | String | 属性値を返します。 |
XPathの書式
次にXPathの書式を示します
軸::ノード[式]
| 簡略化書式 | 意味 |
|---|---|
| 記述省略 | 子 |
| @ | 属性 |
| . | カレントノード |
| .. | 親 |
| / | すべてのノード |
XMLデータはツリーとしてモデル化でき、また、要素や属性などXMLデータを構成する各パーツは、ツリーを構成するノードとしてモデル化できます。XPathのデータモデルでは、XMLデータを以下の7種類のノードから構成されるツリーと考えます。
| 構文 | 意味 |
|---|---|
| / | ルートノードを選択します |
| . | コンテキストノード(現在位置のノード)を選択します。 |
| .. | コンテキストノードの親を選択します。 |
| name | 子要素nameまたは属性name(子要素と属性の区別は軸で指定) |
| * | 指定したパスの直下の全ての子要素または属性(子要素と属性の区別は軸で指定) |
| text() | 指定したパスの直下のテキストを選択します。指定形式:パス/text() |
| node() | 指定したパスの直下のノードを選択します(属性ノードは含みません)。指定形式:パス/node() |
[式]は、「軸::ノード」 で指定した条件をさらに細かく指定するために使用します。例えば、ノードを限定するには、 node_name[2] のように番号を指定するか、node_name[@attrib_name=”value”] のように条件を指定します。条件指定は、and ,orなどで複数指定できます。
コンテキストノードの1番目の子要素bookを選択する場合は、
book[1]
となります。また、条件式に関数を使うこともできます。次の例では、コンテキストノードの最後の子要素bookを選択します。
book[last()]
「following-sibling」 というのは、兄弟ノードのうち後方にあるものを指します。「start/following-sibling::node() 」で、startノードの兄弟ノードのうち後方にあるものすべてを示し、 「following-sibling::end」 で、それより後方にendノードがあること、という条件が付きます。つまりこれで、」 <start/>~<end/> の内部を指すことができます。