JavaA2Z

KAB-studio > プログラミング > JavaA2Z > DOMとは

DOM

日本語 文章物化構造
英語 Document Object Model
ふりがな どむ
フリガナ ドム

解説

XMLを操作するためのクラス集のひとつ。
XML木構造と見なして解析し、タグを「ノード」「エレメント」といった要素に置き換えて処理する。
 
XMLは、タグの中にタグがある、という構造のため、構造が木構造と一致する。
そこで、XML木構造とみなし、タグを「ノード」「エレメント」といった「オブジェクト」と見なして扱うためのクラス群が、DOMである。
 
DOMは、XMLを構成する様々な要素を「ノード」(枝)と呼ぶ。
ノードには、XML全体含む「ドキュメント」、タグひとつを含む「エレメント」、文ひとつを含む「テキスト」も含まれる。つまり「ドキュメント」「エレメント」「テキスト」は「ノード」の一種である。クラス的に言えば、この3つは「ノード」のサブインターフェイスである。
これらを組み合わせて、XMLを表現する。
 
Javaでは、まずDocumentBuilderFactoryインターフェイス及びDocumentBuilderインターフェイスを用いてXMLパーシングする。
対象となるXMLファイル文字列となる。これらはバイト入力ストリームクラスもしくは文字入力ストリームクラスが仲介役となって渡す。
 
XMLの操作は、Nodeインターフェイス、Documentインターフェイス、Elementインターフェイス、TextインターフェイスNodeListインターフェイス等でう。
Nodeインターフェイスは「ノード」を管理するインターフェイスである。
Documentインターフェイスは「ドキュメント」を管理するインターフェイスであり、Nodeインターフェイスサブインターフェイスである。
Elementインターフェイスは「エレメント」を管理するインターフェイスであり、Nodeインターフェイスサブインターフェイスである。
Textインターフェイスは「テキスト」を管理するインターフェイスであり、Nodeインターフェイスサブインターフェイスである。
この3つはすべてNodeインターフェイスサブインターフェイスである。
NodeListインターフェイスNodeインターフェイス配列状に格納するクラスであり、item()メソッドインデックスナンバーを渡すことで任意の位置のNodeインターフェイスを取得することができる。
 
パーシング後、XMLの「ドキュメント」がDocumentインターフェイスという形で返される。
ドキュメント全体を含むタグを「エレメント」として取得する場合、DocumentインターフェイスのgetElementsByTagName()メソッドでElementインターフェイスを取得する。
 
Elementインターフェイスから、その中に入れ子となっている子エレメントや子テキストを取得する場合、NodeListインターフェイスのgetChildNodes()メソッドか、ElementインターフェイスのgetElementsByTagName()メソッドを使用する。
前者はあらゆるノードを取得でき、後者はエレメントのみをタグ名を指定して取得する。
テキストも取得したい場合は前者を、特定のタグのみを取得する場合は後者を使用する。
 
NodeListインターフェイスからNodeインターフェイスを取得する場合にはitem()メソッドを使用する。
取得したNodeインターフェイスは、実際にはElementインターフェイスやTextインターフェイスである。その種別は、NodeインターフェイスのgetNodeType()メソッドで取得する。インターフェイスが分かっていれば、アップキャストして使用する。
 
エレメントやテキストといったノードの作成は、DocumentインターフェイスのcreateElement()メソッドやcreateTextNode()メソッドで作成する。
これらはNodeインターフェイスのappendChild()メソッドで「子供」として追加する。
 
DOMを文字列化やファイル化する場合には、まずDocumentインターフェイスをDOMSourceインターフェイスに、「出力先ストリーム」をStreamResultインターフェイスにセットする。
そして、TransformerFactoryインターフェイス及びTransformerインターフェイスを使用して、XMLを「出力先ストリーム」へと出力する。
 
DOMはややこしい。
とりあえず以下の所を押さえておくこと。
 
・ノードは枝、エレメントはタグ、テキストは文
・エレメントとテキストはノードのサブインターフェイス
・ノードの種類はgetNodeType()メソッドで取得
・子の取得はgetChildNodes()メソッドかgetElementsByTagName()メソッド
タグ内の文はgetChildNodes()メソッドでTextインターフェイスを取得してから
 
あとはXMLを様々な形に変えてみて慣れていくのがいいだろう。
 
DOMはJavaに限らず様々な言語で使用されている。
そのため、DOMはXML操作のデファクトスタンダードになりつつある。
ただし、たとえ同じXMLであっても、Javaと同じ方法で操作できるとは限らないし、また同じJavaでもバージョン等が異なることで同じように操作できるとは限らない。
DOMの操作に全てインターフェイスを使用していることから分かるように、実装クラスは必ずしもはっきりしていない。そのため、使用時に「実際にどのクラスが操作をうのか」は不明である。
実装クラスによって、スペースタブ改行等の解釈の仕方が異なるため、XMLによってパースできるものとできないものがある場合もあるため、注意が必要。

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
import java.io.StringWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Sample
{
    public static void main( String[] args )
    {
        // DOMを使用して、XMLのパーシングを行います。
        
        ByteArrayInputStream byteArrayInputStream = null;
        StringWriter stringWriter = null;
        try
        {
            /** XMLの文字コードです。 */
            String XML_TEXT_ENCODE = "UTF-8";
            /** XMLの基本部分です。 */
            String XML_TEXT_HEADER 
                = "<?xml version='1.0' encoding='UTF-8'?>\n"
                + "<test_xml>\n"
                + "    <test>テストです</test>\n"
                + "</test_xml>\n"
                ;

            // この文字列を、UTF-8形式のbyte型配列として取り出します。
            byte[] bytes = XML_TEXT_HEADER.getBytes( XML_TEXT_ENCODE );
            // そのbyte型配列を対象とする、ByteArrayInputStreamクラスを用意します。
            byteArrayInputStream = new ByteArrayInputStream( bytes );

            // パーサーを作ります。
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            // パーシングします。
            Document document = documentBuilder.parse( byteArrayInputStream );

            // ここまででパーシングが完了しました。
            // 次はXMLを修正します。

            // ルートエレメント、つまり<test_xml>タグを指すエレメントを取得します。
            Element root = document.getDocumentElement();
            System.out.println( "ルートエレメントの名前:" + root.getTagName() );
            // ルートエレメントの名前:test_xml

            // ルートエレメントの下にあるノードをノードリストとして取得します。
            NodeList testsNodeList = root.getElementsByTagName( "test" );
            // 0番目の要素をノードとして取得します。
            Node testNode = testsNodeList.item( 0 );
            if( testNode.getNodeType() == Node.ELEMENT_NODE )
            {
                // このノードは「エレメント」です。
                System.out.println( "testNode.getNodeValue():このノードは「エレメント」です。" );
                // testNode.getNodeValue():このノードは「エレメント」です。
            }
            // なのでElementインターフェイスにキャストできます。
            Element testElement = (Element)testNode;
            System.out.println( "ルートエレメントの子エレメントの名前:" + testElement.getTagName() );
            // ルートエレメントの子エレメントの名前:test
            
            // <test>タグエレメントの子ノードを取得します。
            NodeList testValuesNodeList = testElement.getChildNodes();
            // 0番目の要素をノードとして取得します。
            Node testValueNode = testValuesNodeList.item( 0 );
            if( testValueNode.getNodeType() == Node.TEXT_NODE )
            {
                // このノードは「テキスト」です。
                System.out.println( "testValueNode.getNodeValue():このノードは「テキスト」です。" );
                // testValueNode.getNodeValue():このノードは「テキスト」です。
            }
            // このテキストに当たる文字列を取得します。
            String testValue = testValueNode.getNodeValue();
            System.out.println( "<test>タグ内の文字列:" + testValue );
            // <test>タグ内の文字列:テストです

            // <test>タグエレメントにtest属性を加えます。
            testElement.setAttribute( "test""value" );

            // エレメントを新規作成してルートエレメントに追加します。
            Element element = document.createElement( "test1" );
            element.appendChild( document.createTextNode( "テストです" ) );
            root.appendChild( element );

            // もうひとつ追加します。
            element = document.createElement( "test2" );
            element.appendChild( document.createTextNode( "テストですって" ) );
            root.appendChild( element );

            // ここまででXMLの修正が完了しました。
            // 最後に出力します。

            // StringWriterクラスを通して文字列に出力します。
            stringWriter = new StringWriter();
            // そのStringWriterクラスをStreamResultクラスに渡して
            // 「出力対象」にします。
            StreamResult streamResult = new StreamResult( stringWriter );
            // XMLドキュメントをDOMSourceクラスに渡して「入力対象」にします。
            DOMSource domSource = new DOMSource( document );

            // 出力用のTransformer実装クラスを作ります。
            TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
            Transformer transformer = transformerFactory.newTransformer(); 

            // 指定した「入力対象」から「出力対象」へと出力します。
            transformer.transform( domSource, streamResult );
            // とりあえず出力。
            System.out.println( stringWriter.toString() );
            // <?xml version="1.0" encoding="UTF-8"?>
            // <test_xml>
            //     <test test="value">テストです</test>
            // <test1>テストです</test1><test2>テストですって</test2></test_xml>

            // このようにXMLを作成することができます。
            // 実際にはこのあとファイルに出力したりサーブレットから
            // 返したりします。
        }
        catch( UnsupportedEncodingException e )
        {
            // StringクラスのgetBytes()メソッドで、存在しない文字コードを
            // 指定された場合にこの例外が投げられます。
            e.printStackTrace();
        }
        catch( TransformerConfigurationException e )
        {
            // TransformerFactoryクラスのnewTransformer()メソッドの
            // 呼び出し中に失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( TransformerException e )
        {
            // TransformerFactoryクラスのtransform()メソッドで
            // 出力に失敗した場合にこの例外が投げられます。
            e.printStackTrace();
        }
        catch( ParserConfigurationException e )
        {
            // DocumentBuilderFactoryクラスのnewDocumentBuilder()メソッドの
            // 呼び出し中に失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( SAXException e )
        {
            // DocumentBuilderクラスのparse()メソッドの呼び出しで
            // パーシングに失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( IOException e )
        {
            // DocumentBuilderクラスのparse()メソッドの呼び出しで
            // パーシングに失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        finally
        {
            // 最後にclose()メソッドを呼んで後処理をします。
            // また、これは必ず行うため、finally内で行います。
            try
            {
                if( stringWriter != null )
                {
                    stringWriter.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( byteArrayInputStream != null )
                {
                    byteArrayInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
}
// Sample.java
import java.io.StringWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Sample
{
    public static void main( String[] args )
    {
        // DOMを使用して、XMLのパーシングを行います。
        
        ByteArrayInputStream byteArrayInputStream = null;
        StringWriter stringWriter = null;
        try
        {
            /** XMLの文字コードです。 */
            String XML_TEXT_ENCODE = "UTF-8";
            /** XMLの基本部分です。 */
            String XML_TEXT_HEADER 
                = "<?xml version='1.0' encoding='UTF-8'?>\n"
                + "<test_xml>\n"
                + "    <test>テストです</test>\n"
                + "</test_xml>\n"
                ;

            // この文字列を、UTF-8形式のbyte型配列として取り出します。
            byte[] bytes = XML_TEXT_HEADER.getBytes( XML_TEXT_ENCODE );
            // そのbyte型配列を対象とする、ByteArrayInputStreamクラスを用意します。
            byteArrayInputStream = new ByteArrayInputStream( bytes );

            // パーサーを作ります。
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            // パーシングします。
            Document document = documentBuilder.parse( byteArrayInputStream );

            // ここまででパーシングが完了しました。
            // 次はXMLを修正します。

            // ルートエレメント、つまり<test_xml>タグを指すエレメントを取得します。
            Element root = document.getDocumentElement();
            System.out.println( "ルートエレメントの名前:" + root.getTagName() );
            // ルートエレメントの名前:test_xml

            // ルートエレメントの下にあるノードをノードリストとして取得します。
            NodeList testsNodeList = root.getElementsByTagName( "test" );
            // 0番目の要素をノードとして取得します。
            Node testNode = testsNodeList.item( 0 );
            if( testNode.getNodeType() == Node.ELEMENT_NODE )
            {
                // このノードは「エレメント」です。
                System.out.println( "testNode.getNodeValue():このノードは「エレメント」です。" );
                // testNode.getNodeValue():このノードは「エレメント」です。
            }
            // なのでElementインターフェイスにキャストできます。
            Element testElement = (Element)testNode;
            System.out.println( "ルートエレメントの子エレメントの名前:" + testElement.getTagName() );
            // ルートエレメントの子エレメントの名前:test
            
            // <test>タグエレメントの子ノードを取得します。
            NodeList testValuesNodeList = testElement.getChildNodes();
            // 0番目の要素をノードとして取得します。
            Node testValueNode = testValuesNodeList.item( 0 );
            if( testValueNode.getNodeType() == Node.TEXT_NODE )
            {
                // このノードは「テキスト」です。
                System.out.println( "testValueNode.getNodeValue():このノードは「テキスト」です。" );
                // testValueNode.getNodeValue():このノードは「テキスト」です。
            }
            // このテキストに当たる文字列を取得します。
            String testValue = testValueNode.getNodeValue();
            System.out.println( "<test>タグ内の文字列:" + testValue );
            // <test>タグ内の文字列:テストです

            // <test>タグエレメントにtest属性を加えます。
            testElement.setAttribute( "test", "value" );

            // エレメントを新規作成してルートエレメントに追加します。
            Element element = document.createElement( "test1" );
            element.appendChild( document.createTextNode( "テストです" ) );
            root.appendChild( element );

            // もうひとつ追加します。
            element = document.createElement( "test2" );
            element.appendChild( document.createTextNode( "テストですって" ) );
            root.appendChild( element );

            // ここまででXMLの修正が完了しました。
            // 最後に出力します。

            // StringWriterクラスを通して文字列に出力します。
            stringWriter = new StringWriter();
            // そのStringWriterクラスをStreamResultクラスに渡して
            // 「出力対象」にします。
            StreamResult streamResult = new StreamResult( stringWriter );
            // XMLドキュメントをDOMSourceクラスに渡して「入力対象」にします。
            DOMSource domSource = new DOMSource( document );

            // 出力用のTransformer実装クラスを作ります。
            TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
            Transformer transformer = transformerFactory.newTransformer(); 

            // 指定した「入力対象」から「出力対象」へと出力します。
            transformer.transform( domSource, streamResult );
            // とりあえず出力。
            System.out.println( stringWriter.toString() );
            // <?xml version="1.0" encoding="UTF-8"?>
            // <test_xml>
            //     <test test="value">テストです</test>
            // <test1>テストです</test1><test2>テストですって</test2></test_xml>

            // このようにXMLを作成することができます。
            // 実際にはこのあとファイルに出力したりサーブレットから
            // 返したりします。
        }
        catch( UnsupportedEncodingException e )
        {
            // StringクラスのgetBytes()メソッドで、存在しない文字コードを
            // 指定された場合にこの例外が投げられます。
            e.printStackTrace();
        }
        catch( TransformerConfigurationException e )
        {
            // TransformerFactoryクラスのnewTransformer()メソッドの
            // 呼び出し中に失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( TransformerException e )
        {
            // TransformerFactoryクラスのtransform()メソッドで
            // 出力に失敗した場合にこの例外が投げられます。
            e.printStackTrace();
        }
        catch( ParserConfigurationException e )
        {
            // DocumentBuilderFactoryクラスのnewDocumentBuilder()メソッドの
            // 呼び出し中に失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( SAXException e )
        {
            // DocumentBuilderクラスのparse()メソッドの呼び出しで
            // パーシングに失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        catch( IOException e )
        {
            // DocumentBuilderクラスのparse()メソッドの呼び出しで
            // パーシングに失敗するとこの例外が投げられます。
            e.printStackTrace();
        }
        finally
        {
            // 最後にclose()メソッドを呼んで後処理をします。
            // また、これは必ず行うため、finally内で行います。
            try
            {
                if( stringWriter != null )
                {
                    stringWriter.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }

            try
            {
                if( byteArrayInputStream != null )
                {
                    byteArrayInputStream.close();
                }
            }
            catch( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/11/30
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。