XMLをJavaで扱う

SAXとDOM XMLからデータを読んでDBへ…、という機能を作りました。 JavaXMLを操作する際は、SAX (Simple API for XML)とDOM(Document Object Model)という標準APIが使えます。オープンソースXML解析ライブラリもどちらかを使っています。

今回は以下のようなXMLを読込み実験しました。 [xml]<?xml version="1.0" encoding="Shift_JIS" ?> <root> <aaa>あいうえお</aaa> </root>[/xml] XMLW3Cの規約に沿っていないと読み込み時に例外が発生します。 マルチバイト文字の数字とか、括弧とかもです。(意外)

SAXはXML文書を先頭から順に読んでいき、発生したイベント(タグが始まった、終わった等)をアプリケーションでとらえて処理するAPIです。 ノードに階層の深さが決まりきっているXMLを読む際は便利です。 実装はorg.xml.sax.helpers.DefaultHandlerを継承したHandlerクラスを作成します。 [java]package test;

import org.xml.sax.; import org.xml.sax.helpers.;

public class SampleHandler extends DefaultHandler {

public void startDocument() { //ドキュメント開始 } public void endDocument() { //ドキュメント終了 } / * @param namespaceURI * @param localName * @param qName * @param atts */ public void startElement (String namespaceURI, String localName, String qName, Attributes atts) { // 要素の始まりの処理 } / * @param namespaceURI * @param localName * @param qName */ public void endElement(String namespaceURI, String localName, String qName) { System.out.println("</"+qName+">"); } public void characters(char ch, int start, int length) { // 要素の間の値 } }[/java] 上で作ったHandlerはこのように使います。 [java] SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); String url = "read_test.xml"; // XML文書の実際のURL SampleHandler handler = new SampleHandler("a"); parser.parse(url, handler);// これで解析ができる。[/java] DOMは要素の入れ子階層が不確定なときにwhileなどで使うのに便利です。 [java]package test;

import java.io.*;

import org.w3c.dom.Document; import org.w3c.dom.Node; import javax.xml.parsers.*;

/* * @author nakaya * * $Log: $ / public class NodeSample {

private static final String nodeNameText = "#text"; public static void main(String args) throws Exception{ // XMLファイル読込 Document document= DocumentBuilderFactory.newInstance() .newDocumentBuilder().parse(new File("read_test.xml")); // ルートノード Node rootNode = (Node)document.getDocumentElement();

// 最初のノード Node firstNode = rootNode.getFirstChild(); while (null!=firstNode) { // ノード名 String nodeName = firstNode.getNodeName(); if (nodeName.equals(nodeNameText)) { firstNode = firstNode.getNextSibling(); continue; } else if (nodeName.equals("aaa")) { threeNestings(firstNode); } else if (nodeName.equals("bbb")) { threeNestings(firstNode); } firstNode = firstNode.getNextSibling(); } }

/* * 入れ子が2段階 * @param firstNode / private static void twoNestings (Node firstNode) { Node secondNode = firstNode.getFirstChild(); while (null!=secondNode) { String nodeName2 = secondNode.getNodeName(); if (!nodeName2.equals(nodeNameText)) { System.out.println(nodeName2 + " : " + secondNode.getFirstChild().getNodeValue()); } secondNode = secondNode.getNextSibling(); } }[/java] どちらにせよ、XMLの書式は始めにきっちり決めておいた方が作りやすいのは間違いないですが…。