ホームページへ戻る
 

上へ戻る
 

    XML入門  その2  DOM     by H.Y   

目次
1。XML文書の解析 (DOM と SAX)
1ー1。DOM
1ー2。SAX
2。XML パーサ
2ー1。基本的な特徴
2ー2。DOM による XML 文書のパース
1)クラスとインターフェイ』
2)DOM のインターフェイス (クラス)
3) DOM クラスのリンク関係
2ー3。主な DOM ツリーの構成要素
1) Node
2) Element
3)Text
4)Document
2ー4。DOM ツリーのノード
1) 例1
2)課題
3。DOM プログラミング
3ー1。DOM ツリーの生成
1) 基本形式
2) 課題
3ー2。Node (ノード操作)
1)ノード参照のメソッドの種類
(1)メソッド一覧
(2)getChildNodes の例
(3)getFirstChild, getNextSibling の例
(4)netLastChild, getPreviousSibling の例
2)ノード更新のメソッド
3) ノード操作のサンプルプログラム
3ー3。Element
1)Element のメソッド
2)ノード操作
3) getElementByTagName
4)正規化
5)使用例
3ー4。Text
1)重要なメソッドは
2)参照 での使用例
3)更新 での使用例
3ー5。Document
1)Document からの リンク
2)getDocumentElement
3)getElementsByTagName
4) ファクトリ
5)使用例
3ー6。DOMException
3ー7。NodeList
1)取得の仕方
2)メソッド
3)使用例


==========================================================================================
1。XML文書の解析 (DOM と SAX)
XML文書をプログラムから利用するには、XMLプロセッサを利用する。XMLプロセッサは、XML文
書を解析するための、ソフトウェアライブラリである。
XMLプロセッサの API には DOM(Document Object Method) と SAX(Simple API for XML)がある。
一般的に、XML構造の複雑な操作を必要としないアプリケーションには SAX が、複雑な操作
を必要とする場合には DOM が向いている。

1ー1。DOM
W3Cで策定している API で、解析後に XML 文書を表現する、論理ツリーを定義する。
DOM では、XML 文書の内部表現として、いくつかのインターフィエスを定義している。
詳細については、参考資料を参照のこと。-------> [DOM インターフェイス]
1ー2。SAX
SAX API では、XML 文書のいろいろな部分(タグ、属性、テキストなど)を解析するメソッド
を定義するハンドラのインターフェイスを既定している。SAX の API では、Java 言語用の
API のみを規定している。他言語のインターフェイスの規定はない。

2。XML パーサ
2ー1。基本的な特徴
DOM 用 XML パーサは、ドキュメント・オブジェクトへのアクセスを提供するインターフェイス
である。
このパーサは、指定された XML 文書を順次入力しながら、DOM のオブジェクトを階層的に構築
する。この DOM オブジェクトは、 DOM ツリーと呼ばれている。構築した DOM オブジェクトは、
パース完了後にアプリケーションから取得できる。アプリケーションは、取得したオブジェクト
の各メソッドを呼び出すことにより、XML 文書にアクセスすることが出来る。

2ー2。DOM による XML 文書のパース
DOM の「ドキュメント・オブジェクト」では、XML 文書の各構成要素毎に、構成要素に対応
したオブジェクトとして記憶領域が割り当てられる。このオブジェクトのことを「ノード」と
言う。
ノードを表現するインターフェイスは幾つかあり、これらは、Node インターフェイスを基底に
している。
このインターフェイスの継承関係は、参考資料を参照のこと。
-------->[DOM クラス インヘリタンス]
また、これらのインターフェイスの中で、NodeLinst, NamedNodeMap,DOMImplemetation,
DOMException は Node を継承していない。
1)クラスとインターフェイ』
DOM のインターフェイスは クラスと同一の意味でつかわれている。
2)DOM のインターフェイス (クラス)
(1) Nodeクラス
DOM のノードを表現する。ほとんどのインターフェイスの親インターフェイスで,ノード操
作の共通機能を定義する。
(2) Elementクラス
XML のタグに対応するノード。
(3) Textクラス
タグの中に記述されている記述を格納するノード。
(4) Documentクラス
XML 文書全体をあらわすノード。
(5) DOMExceptionクラス
DOM 使用時の例外を扱うノード。
(6) NodeLiestクラス
DOM ノードをアクセスするための、イテレータである。DOM ツリー操作のためのヘルパー
である。
並び順にいみのあるノードを収容するための「コレクション」を表現している。
あるノードに属する下位の文書要素や文字データをXML文書内での出現順に管理するために
使用される。Element や Text 等のインスタンスを要素に持つ。 see NamedNodeMap
(7) Attrクラス
属性を表す。属性の取り出しは Element の getAttribute メソッドでも可能であるので、
あまり必要性がない。
(8)CharacterDataクラス
文字列を格納するノードの性質を代表するノード。
Text, CDATASection, Comment がサブクラスである。
実際のプログラミングでは, Text をつかうことがほとんどである。
(9) CDATASectionクラス
CDATA セクションを表す。 CDATASection は Text のサブクラスである。
(10) EntityReferenceクラス
EntityReference を表すノード。
(11) ProcessingInstructionクラス
(12) Commentクラス
(13) DocumentTypeクラス
(14) Entity クラス
(15) Notationクラス
(16) DocumentFramentクラス
DOM ツリーの一部をポイントするためのノードである。
(17) DOMImplemetationクラス
DOM のインプリメンテーション状態を通知するため。
(18) NamedNodeMapクラス
ノードの一覧から、名前付きでアクセスするためのマップである。おもに属性のアクセ
スに用いられる。
並び順に意味はないが、名前をキーにして値を参照する必要があるノードを収容するコ
レクションである。
3) DOM クラスのリンク関係
Document は XML ドキュメント全体を代表するクラスである。XML ドキュメントを構成する
要素は、このクラスを起点にして探索することができる。
[Document からのリンク]
[Element からのリンク]
参照のこと。

2ー3。主な DOM ツリーの構成要素
1) Node
org.w3c.dom.Node は、DOM で最も重要なクラスである。Node は DOM のノードの基本的な
性質を代表している。
Node の提供するメソッドのいくつかは「一部のノードの性質のみを代表する」ものがある。
参考資料[ノードクラスのメソッドと戻り値]のように
getNodeName,getNodeValue,getAttributes メソッドは、ノードによって処理がことなる。
2) Element
XML の最重要構成要素の「タグ」を表すノードである。
Element のメソッドに、親クラスである Node のメソッドも加えて提供される。
重要なのは、
getTagName
getElementsByTagName
getAttribute, setAttribute, removeAttribute
3)Text
重要なメソッドは
getData String をとりだす。
setData
getLength
4)Document
XML ドキュメント全体を表すクラス。
ドキュメントを構成するタグを取り出す、次のメソッドが重要である。
getDocumentElement
getElementTagName

2ー4。DOM ツリーのノード
1) 例1
------------- test.xml -----------------------------
<Tag_root>ここはテキストノードです。
<Tag2>タグ2間のテキストです。
<Tag2_2> tag2-2 TEXT</Tag2_2>
</Tag2>
<Tag4>Tag4 間の TEXT</Tag4>
<Tag6>Tag6 間の text</Tag6>ここもテキストノードです。
</Tag_root>
------------------------------------------------------------------------------
ノードの親子関係は次のとおりになる。

(0)ルートノードは <Tag_roo> ELEMENT_NODE
(1)1番目の子ノードは、 "ここはテキストノードです。" と
<Tag2> までの ホワイトスペースすべて。 TEXT_NODE
(2)2番目の子ノードは、 <Tag_2> ELEMENT_NODE
(2-1)2番目の子ノードの 1番目の子ノードは
<Tag2_2>までのホワイトスペース TEXT_NODE
(2-2)2番目の子ノードの 2番目の子ノード は、"Tag2-2 TEXT" TEXT_NODE
(2-3)2番目の子ノードの 3番目の子ノード は、<Tag2-2> ELEMENT_NODE
(2-4)2番目の子ノードの 4番目の子ノード は
</Tag2_2>から</Tag2>までのホワイトスペース TEXT_NODE
(3)3番目の子ノードは、<Tag4> の前までのホワイトスペース TEXT_NODE
(4)4番目の子ノードは <Tag4> ELEMENT_NODE
(4-1)4番目の子ノードの、1番目の子ノードは "Tab4 間の TEXT" TEXT_NODE
(5)5番目の子ノードは </Tag4>から<Tag6>までのホワイトスペース TEXT_NODE
(6)6番目の子ノードは <Tag6> ELEMENT_NODE
(6-1)6番目の子ノードの、1番目の子ノードは、"Tag6 間の text" TEXT_NODE
(7)7番目の子ノードは "ここもテキストノードです。" TEXT_NODE
----------------------------------------------------------------------------
これをツリーで表すと以下のようになる。
<Tag_root>
|
|---1-----"ここはテキストノードです。" ......(TEXT_NODE)
|
|---2-----<Tag2> ...........................(ELEMENT_NODE)
| |
| |--- 1-1 -----"" (TEXT_NODE)
| |
| |--- 1-2 ---- "Tag2-2 TEXT" (TEXT_NODE)
| |
| |--- 1-3 --- <Tag2-2> (ELEMENT_NODE)
| |
| --- 1-4 --- "" (TEXT_NODE)
|
|---3---"" .................................(TEXT_NODE)
|
|---4------<Tag4> ...........................(ELEMENT_NODE)
| |
| --- 4-1 --- "Tab4 間の TEXT" (TEXT_NODE)
|
|---5---"" .................................(TEXT_NODE)
|
|---6------<Tab6> ..........................(ELEMENT_NODE)
| |
| --- 6-1 ---"Tab6 間の TEXT" (TEXT_NODE)
|
--7---"ここもテキストノードです。" ........(TEXT_NODE)

2)課題
test.xml のホワイトスペースを全て取り去った場合の DOM ツリーを作れ。

3。DOM プログラミング
3ー1。DOM ツリーの生成
1) 基本形式
DocumentBuilderFactory factory = DocumentBuilerFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(uri);

Well formed document の場合は
factory.setValidating(false);
Valid document の場合は
factory.setValidationg(true);

-------- sample program ------------------
import java.io.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

class test {
File objfile;
Document document = null; // return するときは、あらかじめ定義しておく。
public Document getdocument(File file) {
try{
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(file);
}
catch(Exception e){
e.printStackTrace();
System.exit(1);
}
return document;
}
}
2) 課題
xml ファイル名を引く数として DOM オブジェクトを返すパッケージを作成せよ。
test.java とする。

3ー2。Node (ノード操作)
1)ノード参照のメソッドの種類
(1)メソッド一覧
(1) getParentNode 親ノードを通知する。
(2) hasChildNodes 子ノードの有無を通知する。
(3) getChildNodes NodeList を用いて全ての子ノードを通知する。
(4) getFirstChild ノード内の先頭のノードを通知する。
(5) getLastChild ノード内の最後のノードを通知する。
(6) getPreviousSibling 自ノードの直前のノードを通知する。
(7) getNextSibling 自ノードの直後のノードを通知する。
(2)getChildNodes の例

public List getChildren( Node node ) {
List list = new ArrayList();
NodeList children = node.getChildNodes();
int size = childeren.getLength();
for(i = 0; i < size; i++)
list.add(children.item(i);
return (list);
}
(3)getFirstChild, getNextSibling の例
ランダムアクセスの方法である。

public List getChildren(Node node){
List list = new ArrayList();
for( Node child = node.getFirstChild();
child != null;
child = child.getNextSibling() ){
list.add(child);
}
}
(4)netLastChild, getPreviousSibling の例

public List getChildren(Node node){
List list = new ArrayList();
for( Node child = node.getLastChild();
child != null;
child = child.getPreviousSibling() ){
list.add(child);
}
}
2)ノード更新のメソッド
(1) isertBefor 指定したノードの前に、新しいノードを追加する。
(2) appendChild 親ノードの最後尾に、新しいノードを追加する。
(3) replaceChild
(4) removeChild
3) ノード操作のサンプルプログラム

public void printNodeValues(Node node){
NodeList children = node.getChildNodes();
int size = children.getLength();
for ( int i = 0; i < size; i++){
Node child = chidren.item(i);
String value = child.getNodeValue();
System.out.println(value);
}
}
4) 課題
test.java を使って、次の機能を有するプログラムを作成せよ。
(1) 引数で指定した、XML文書を読み込む。
(2) これを parse して 画面に出力する。
System.out.println(document.getNodeElement); をつかう。
document は Document 型の DOM オブジェクト
(3) ノード操作メソッドで、ルートノードの子ノードの値を出力する。

3ー3。Element
Element のメソッドに、親クラスである Node のメソッドも加えて提供される。
1)Element のメソッド
重要なのは、
getTagName
getElementsByTagName
getAttribute, setAttribute, removeAttribute
2)ノード操作
getParentNode
getChildNodes
等 Node メソッドと同じ機能がある。
3) getElementByTagName
このメソッドは、ノードの配下にある指定されたタグ名を持つ全ての Element の一覧を取得
する。 このメソッドは、直下の子供ノードだけでなく、全ての子孫ノードを検索対象とし
ている。直下の子供ノードのみを検索したい場合は注意を要する。
4)正規化
normalize メソッドは、複数の連続した Text を一つにまとめる正規化処理を行う。
5)使用例

Public String getAttribute(Element element, String attrName){
Attr attr = element.getAttribureNode(attrName);
if (attr == null)
return (null);
else
return (attr.getValue() );
}

3ー4。Text
Text は CharacterData のサブクラスである。タグの中に書かれたテキスト、つまり DOM で
データとして扱わなければならないテキストは、この Text に格納される。
CDATASection は Text のサブクラスなので、CDATASection も Text である。
1)重要なメソッドは
getData
setText
getLength
2)参照 での使用例
Public String getText(Text text){
return (text.getData() );
}
3)更新 での使用例
Public String setText(Text text, String string){
text.setData(string);
}

3ー5。Document
Document は XML ドキュメントのルートノードとして、XML 文書全体を代表するクラス
である。また、ノード生成のファクトリクラスとして、さらにノードの管理者として重要な
役割を担っている。
1)Document からの リンク
(1) Element
Docoment の getDocumentElement メソッドを使う。 重要なメソッドである。
(2) DOMImplementation
getImplementation メソッドを使う
(3) DocumentType
getDocType メソッドを使う
2)getDocumentElement
Document に格納されているルートのエレメントを取得するためのメソッドである。
Document の最重要メソッドである。

3)getElementByTagName
Element の getElementByTagName と同じ機能を持ったメソッド。
ノードの配下にある指定されたタグ名を持つ全ての Element 一覧を通知する。
4) ファクトリ
new を使わずに、「ファクトリ」と言うメカニズムを使って、オブジェクトを生成する。
ファクトリとは、クライアントがオブジェクトを生成するためのファクトリクラスに対して
オブジェクトの生成を依頼する方式である。
DOM プログラミングにおいて、ノードの生成は、この Document の提供するファクトリ機能
を持つメソッド以外では行うことができない。
Document のファクトリを使って、以下のノードを生成できる。
(1)Element
(2)DocumentFragment
(3)Text
(4)Comment
(5)CDATASection
(6)ProcessingInstruction
(7)Attribute
(8)EntityReference
create******** メソッドを用いる。
例:createElementメソッド
5)使用例
public Element getRootElement (Document doc){
return (doc.getDocumentElement() );
}

3ー6。DOMException
DOM で発生するエラーを通知するための例外クラスである。
このクラスは、java.lang.RuntimeException を継承している。
DOMException はメソッドを追加していないので、RuntimeException のメソッドをそのまま
継承している。
public インスタンス変数 code が定義されているので、エラーの詳細情報を取得すること
ができる。このコードの一覧は参考資料を参照のこと。

3ー7。NodeList
NodeList はノード内の要素をアクセスするための、イテレータである。
1)取得の仕方
(1) Node の getChildNodes メソッドを使う。
(2) Element の getElementsByTagName メソッドを使う。
(3) Document の getElementsByTagName メソッドを使う。
2)メソッド
(1) getLength ノード数の通知
(2) item インデックスに対応するノードの通知
3)使用例
public void printText(Node node){
NodeList nodes = node.getChildNodes();
int size = node.getLenght();

for ( i = 0; i < size ; i++){
Node child = node.item(i);
if ( child.getNodeType() == TEXT_NODE ){
Text text = (Text)child;
System.out.println(text.getData() );
}
}
}
// System.out.println(child.getNodeValue() ); でも可
-------------------------------------------------------

3ー8。Attr
エレメントに格納されている属性を格納するためのノードである。
1)メソッド
(1)getName
(2)
2)使用例
Element に格納されている、属性名とその値をとりだして表示する。
public void printAttributeList(Element node){
NameNodeMap attrs = node.getAttributes();
int size = attrs.getLength();
for (int i = 0; i < size; i++){
Attr attr = (Attr)attrs.item(i);
String name = attr.getName();
String value = attr.getValue();
System.out.println("name = " + name);
System.out.println("value = " + value);
}
}

3ー9。サンプルプログラム
XML ファイルを詠み込んで、parse してDOM ツリーを作成し、各ノードの種別と
値を表示する。
1) プログラム名 domlist.java
2) 使用法 domlist *.xml