JavaでXMLメモ

JavaからXMLにアクセスする。
JDK 1.4.2


XMLにアクセスする方法として、主に2種類あるらしい。

  • DOM
    • メモリ上にツリー構造で保持する。
    • 重い。
  • SAX
    • イベントで処理する。
    • DOMより軽い。
    • XMLの更新はできない。

20MくらいのXMLをDOMで操作していたら、あまりに重くて使い物にならなかった
プロジェクトがあるのは、ここだけの話。まぁプロジェクト=自分1人なわけだが。


とりあえずDOMを試す。

読み込む1

単純なXMLを読み込んでみる。
まずはXMLの中身。内容は適当。




ykhr
25
Java


kokko
22
Game



んでJavaコード。


public static void main(String[] args) {
try {
DocumentBuilder builder
= DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new File("ykhr-kokko1.xml"));

NodeList nodeList = doc.getElementsByTagName("person");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String name = getChildTagValue(element, "name");
String age = getChildTagValue(element, "age");
String hobby = getChildTagValue(element, "hobby");
System.out.println(name + "-" + age + "-" + hobby);
}

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

private static String getChildTagValue(Element element, String tagName) {
NodeList nodeList = element.getElementsByTagName(tagName);
if (nodeList == null || nodeList.getLength() == 0) {
return null;
}
return nodeList.item(0).getFirstChild().getNodeValue();
}

実行結果。

ykhr-25-Java
kokko-22-Game

要素の内容として値を持っていると、少しめんどくさい。
なので、次に属性として持っている場合を試してみる。

読み込む2

属性バージョン。
まずはXML






そしてJavaソース。

public static void main(String[] args) {
try {
DocumentBuilder builder
= DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new File("ykhr-kokko2.xml"));

NodeList nodeList = doc.getElementsByTagName("person");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String name = element.getAttribute("name");
String age = element.getAttribute("age");
String hobby = element.getAttribute("hobby");
System.out.println(name + "-" + age + "-" + hobby);
}

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
実行結果はさっきと同じ。


属性の方がラクな気がする。
XMLを出力するツールたちは、なんかポリシーを持って
決めているのだろうか・・・。

作る

Java内でXMLを作成して出力してみる。
ソースはこんな感じ。めんどくさいので属性1つのみ。


public static void main(String[] args) {
try {
// 作成
DocumentBuilder builder
= DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.newDocument();

Element root = document.createElement("root");
document.appendChild(root);
Element person1 = createChildElement(root, "person");
person1.setAttribute("name", "ykhr");
Element person2 = createChildElement(root, "person");
person2.setAttribute("name", "kokko");

// 出力
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File("ykhr-kokko3.xml"));
Transformer transformer
= TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);

} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}

private static Element createChildElement(Element parent, String tagName) {
Document doc = parent.getOwnerDocument();
Element child = doc.createElement(tagName);
parent.appendChild(child);
return child;
}


実行結果(ykhr-kokko3.xmlの内容)。


<?xml version="1.0" encoding="UTF-8"?>




出力の方は以外に簡単。
使う機会があるかは知らんけど。

おわり

正直、色々とめんどい。もっとシンプルにアクセスしたい。
やっぱオブジェクト-XML間のバインディングをしてくれるものを
使ったほうがいいのかも。


世の中的にはDOMのAPIが貧弱だという方がいるらしい。
だからJDOMとかがあるとか・・・。
やべぇ、全然貧弱と思わなかったorz