しいしせねっとわーくAmazon.co.jp アソシエイト
[技術資料室] [XML] [Java] [J2EE] [Java XML]

Javaで使うXML

おしながき

必要な基礎知識

はじめに?

Javaに限らず XMLを使うには、Document Object Model(DOM)とSimple API for XML(SAX)という2種類のAPIによるアクセス方法があるらしい。
DOMがツリー・ベースのAPI というのはわかるが、SAXがイベント・ベースのAPIらしい。
DOMは、アプリケーション側からアクセスする、SAXは、XMLツリーを先頭から順に読んでいき、要素の開始や終わりといったところでXMLからアプリケーションへイベント通知がされる。
まぁ、最初はSAXはわからんでもよしとしよう。
XMLをテキストエディタで用意せずにプログラムから書き出して用意して、なんてのがいいかな。

参考

DOM

DOMは実装の程度によって、3種類のレベルに分けられているらしい。レベル3のDOM対応だと、DOMの全機能が使えるようだ。
オブジェクト・モデルと、それにアクセスするためのAPI等の2つが決められているらしい。
DOMはどの言語でも同じように使える。そのため、Javaに馴染まない部分もあるようだ。JavaではJDOMというのもあるらしい。

org.w3c.dom パッケージ

DOMの基本は Nodeから連なるデータ形式の組み合わせのようなもので、すべてNodeとして扱うと楽かもしれないということのようです。初期化の手順はJAXPに頼っているので、まずはそこから見てみましょう。

JAXP になる

DOMやSAXは、各実装によって初期化の方法がまちまちになってしまったので、その部分まで含めて標準化したのがJAXPというAPIらしい。JAXP 1.1でXSLT関連の初期化部分も含む? 最新版は1.2.4 ?
Java 2 SDK 1.4 にも含まれるようになったのかな?

基本的にJAXPのみ関係あるのは javax.xml.parsers パッケージ? org.w3c.dom DOM、SAXなどの初期化をするためのものなので、DOMやSAXの実装と組み合わせて使います。

其の一 作る、読み込む

javax.xml.parsers.DocumentBuilderFactory からはじまり、DocumentBuilder をつくる、そこで新しいDocument を作るか ファイルなどから読み込んでDocumentを生成する。ここまでがJAXPの役割のようです。

// DocumentBuilderFactoryはJDBCのDriverManagerみたいなものかな
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
// 作る場合
org.w3c.dom.Document doc = db.newDocument();
// 読み込む場合
doc = db.parse(File、InputStreamなど);

String からDocument を作ることはできない? org.xml.sax.InputSource というのを使う? これでInputStreamではなくReaderが使えるようになるのかな。Readerが使えると、StringからReaderを作ることができるので、読み込めるかな。DocumentBuilderでparseします。

其の二 書き出す

ファイルに書き出すにはどうすればよいのでしょうか? javax.xml.parsers パッケージや org.w3c.dom のなかには、それらしい機能がありません。しかし、標準の入出力に使える機能があったのです。

javax.xml.transform パッケージとそのサブパッケージを発見してください。このパッケージでXMLの変換ができます。変換元、変換先に、Nodeや各種ストリームなどが指定できるので、この機能を使ってファイルへの書き出しもすることができます。

javax.xml.transform.TransformerFactory tff = javax.xml.transform.TransformerFactory.newInstance();
Transformer tf = ttf.newTransformer();
javax.xml.transform.dom.DOMSource src = new DOMSource();
src.setNode(doc); // 保存したいXMLドキュメントなど org.w3c.dom.Document
javax.xml.transform.stream.StreamResult target = new javax.xml.transform.stream.StreamResult();
target.setStream(new FileOutputStream()); // 書き出したいストリームを設定
tf.transform(src.target); // 変換

逆に読込みもできそうですね。これは、XSLTのための機能を一部使ってみたものです。

メモ

Reader/Writerが使えない?

XMLは、文字のエンコードを<?xml version="1.0" charset="" ?> として指定できるので、基本的にInputStream/OutputStreamを使い、パーサが文字コードを判定するようです。

ファイルにしないといけない?

StringからのXML生成は、一度ファイルに書き出さないといけないかというと、そんなことはありません。PipedInputStream、PipedOutputStreamなどを使えばテキストエディタなどで編集したXMLをDOMツリーに変換することができます。

javax.xml.parsers ではストリームのみでしたが、javax.xml.teansform.dom などではReader や Writer も使えるようです。

XSLT

というわけで、XMLの標準にはXSL Translations ってのがあります。これは、XMLをストリームに書き出すだけではなく、XML、HTMLなどの形に変換することができます。
Javaでは、JAXPに含まれる。Apache Xalanなどの実装がある。パッケージは先程のjavax.xml.transformがXSLTの機能だったりするのです。

TransformerFactory factory = TransformerFactory.newInstance();
// XSLTをセットする
Source xslsource = new DOMSource(): // スタイルとなるXSL
(略)
// Transformerを取得する その1の方法
Templates template = factory.newTemplates(xslsource);
Transformer tf = templates.newTransformer();
//または その2の方法
Transformer tf = factory.newTransformer(xslsource);
(以下同文)

参考

DOMそれから

読み書きの方法がわかったところで、肝心のDOMでXMLを編集する方法について

DOMでは、Document、Node、Element、Attr、Textなどがあります。要素をつくるには、new Node() などとすることができないので、Documentクラスからつくります。createするだけでは、docの中にあるわけではないようです。たぶん。org.w3c.dom パッケージを見れば、だいたいどんな感じなのかわかると思います。

org.w3c.dom.Nodeからの継承構造になっているので、ほとんどの型を同じように扱えます。

追加する

新しい要素(タグ)を追加するには、Documentから要素をつくり、それを親となる要素に追加します。

Document doc;
Element e = doc.createElement("document");
Element name = doc.createElement("name");
name.appendChild(doc.createTextNode("どきゅめんと"));
e.appendChild(name);
doc.appendChild(e);

そうすると、こんな感じの構造になるでしょうか

<?xml version="1.0" ?>
<document>
<name>どきゅめんと</name>
</document>

参照する

DOMにはXPathのようなものはないのかな? DOM Level 3でXPath的な使い方ができるようになるらしいですが、今はDOM Level 2とかLevel 1とかのようなので、いろいろと使い方があるようです。

SAX (Simple API for XML)

SAXは、XLink、XPointerやXML Schemaをサポートしている?

DTD

XMLで何か忘れていませんか、というふうにプログラム作るときに忘れてしまいそうになるのがDTDです。XML Schemaってのもあるけど、それはまた別の機会に・・・。

JavaでDTDというと、XMLファイルなどを取り込むときにチェックしたいときがあったりするからでしょうね。さて、どこを見てみようか。SAXのDefaultHandler、DTDHandlerの2つがあやしそうですね。

XML名前空間は?

ここまでは、名前空間について意識しませんでしたが、名前空間はそもそもどのようにすれば扱えるのでしょうか。名前空間は何かというと、最近流行りのRSSなどで複数のXMLスキーマをあわせるときに使われていますね。JSPなどでも<jsp:include > などとして使っているjsp: の部分です。

DTDでは名前空間がサポートされていません。まずはXML Schemaを使わないといけないようです。

各種XML実装

ここまでは、標準的なXMLの使い方を紹介してみました。ApacheやSun、IBMなどからリリースされているXMLパーサのどれを使っても、同じ方法で使えます。固有のAPIは使っていません。
雑誌などの記事では、固有のAPIを使って初期化して、DOMツリーなどを読込み、保存は独自に実装する方法などを紹介しているものが多いようですが、JAXPを積極的に使うようにした方がよいでしょう。JAXPで保存する方法を紹介したものは、まだまだ少ないですね。

それでは、どのような実装があるのでしょうか?

Apache XML Projectからは、XalanやXercesなどがあります。Xalanが読み込むときのXMLパーサ、XercesがXSLTの処理をします。昔あったIBMやSunの実装も、Apache XML Projectで統合されているような感じです。

実装を切り換えるには?

設定ファイルを編集します。

参考

いろいろなあれこれ

JavaのXML関係のは、いろいろあってよくわかりません。

Get Thunderbird

[しいしせねっと]