目次へ

2.3. Node

DOMで文書を読む場合、XMLの「要素」や「属性」などのデータは木構造の「節」にあたります。DOMには節の部分を操作する「Node」インタフェースが用意されています。DOMの全てのAPIはこのNodeインタフェースを継承したものになります。

Nodeインタフェースのメソッドには、以下のようなものがあります。

メソッド 内容
public String getNodeName()  ノードの名前(要素名や属性名など)を取得する。
public String getNodeValue() ノードの値(属性値など)を取得する
public short getNodeType() ノードのタイプを取得する。
public Node getParentNode() 親ノードを取得する
public NodeList getChildNodes() 子供ノードを取得する。
public Node getFirstChild() このノードの1番最初の子供ノードを取得する。子ノードがない場合は、nullを返す。
public Node getLastChild() このノードの1番最後の子供ノードを取得する。子ノードがない場合は、nullを返す。
public Node getPreviousSibling() このNodeの直前に記述されているノードを取得する。そのようなノードがない場合、nullを返す。
public Node getNextSibling() このNodeの直後に記述されているノードを取得する。そのようなノードがない場合、nullを返す。
public NamedNodeMap getAttributes() このノードが要素で合った場合、属性の一覧を取得する。要素でない場合は、nullを返す。

また、Nodeには、以下の種類があります。以下のインタフェースは全て、Nodeインタフェースを継承したものになります。ノードがどの種類なのかはgetNodeType()メソッドで取得することができます。前節で紹介した「Document」もNodeの一つです。

Type 内容 getNodeType()の戻り値
Document 文書 Node.DOCUMENT_NODE
DocumentFragment  最小の文書オブジェクト Node.DOCUMENT_FRAGMENT_NODE
DocumentType ドキュメントタイプ("DTD"で定義される) Node.DOCUMENT_TYPE_NODE
EntitiyReference  実体参照 Node.ENTITY_REFERENCE_NODE
Element  要素 Node.ELEMENT_NODE
Attr  属性 Node.ATTRIBUTE_NODE
ProcessingInstruction 処理命令 Node.PROCESSING_INSTRUCTION_NODE
Comment コメント Node.COMMENT_NODE
Text  テキスト Node.TEXT_NODE
CDATASection  CDATAセクション Node.CDATA_SECTION_NODE
Entity 実体 Node.ENTITY_NODE
Notation  記法 Node.ENTITY_NODE

以下に例を示します。

     1  import java.io.*;
     2  import org.w3c.dom.Document;
     3  import org.w3c.dom.Node;
     4  import javax.xml.parsers.*;
     5  
     6  public class NodeSample{
     7      
     8      public static void main(String args[]) throws Exception{
     9          
    10          Document document= DocumentBuilderFactory
    11              .newInstance()
    12              .newDocumentBuilder()
    13              .parse(new File("employees.xml"));
    14          
    15          Node node=document.getDocumentElement();
    16          
    17          Node childNode=node.getFirstChild();
    18          int i=1;
    19          while(childNode!=null){
    20              short type=childNode.getNodeType();
    21              String typeStr="";
    22              switch( type){
    23              case Node.ATTRIBUTE_NODE:
    24                  typeStr +="属性";
    25                  break;
    26              case Node.CDATA_SECTION_NODE :
    27                  typeStr +="CDATAセクション";
    28                  break;
    29              case Node.COMMENT_NODE :
    30                  typeStr +="コメント";
    31                  break;
    32              case Node.DOCUMENT_FRAGMENT_NODE :
    33                  typeStr +="最小の文書のオブジェクト";
    34                  break;
    35              case Node.DOCUMENT_NODE :
    36                  typeStr +="文書";
    37                  break;
    38              case Node.DOCUMENT_TYPE_NODE :
    39                  typeStr +="文書型";
    40                  break;
    41              case Node.ELEMENT_NODE :
    42                  typeStr +="要素";
    43                  break;
    44              case Node.ENTITY_NODE:
    45                  typeStr +="実体";               
    46                  break;
    47              case Node.ENTITY_REFERENCE_NODE :
    48                  typeStr +="実体参照";
    49                  break;
    50              case Node.NOTATION_NODE :
    51                  typeStr +="記法";
    52                  break;
    53              case Node.PROCESSING_INSTRUCTION_NODE :
    54                  typeStr +="処理命令";
    55                  break;
    56              case Node.TEXT_NODE:
    57                  typeStr +="テキスト";
    58                  break;
    59              }
    60  
    61              System.out.println((i++)+"番目の子ノードは"+typeStr+"です。");
    62              childNode=childNode.getNextSibling();
    63              
    64          }
    65          
    66          
    67  
    68      }
    69      
    70  }

これは、employees.xmlのルート要素の子ノードがどのタイプのノードなのか、表示するプログラムです。まず、10-14行目でDocumentノードを取得しています。15行目でルート要素を取得しています。17行目で、"getFirstChild()"メソッドを使用して、ルート要素の最初の子ノードを取得しています。もし、ルート要素に子ノードが存在した場合、子ノードのタイプを判別し、コンソールに表示しています(19-61行目)。最後に、62行目で、getNextSibling()メソッドを使用して次のノードを取得しています。これを繰り返し、ルート要素の全ての子ノードに対して、「何番目の子ノードで、ノードタイプは何か」を表示していきます。

employees.xmlの内容が以下であったとします。

 <?xml version="1.0" encoding="UTF-16" standalone="yes"?>
 <employees>
  <employee>
   <name>山田 太郎</name>
   <office>東京</office>
  </employee>    
  <employee>
   <name>川島 次郎</name>
   <office>東京</office>
 </employee>
</employees>

NodeSampleを実行すると、以下のように表示されます。

$java NodeSample
1番目の子ノードはテキストです。
2番目の子ノードは要素です。
3番目の子ノードはテキストです。
4番目の子ノードは要素です。
5番目の子ノードはテキストです。

employess.xmlのルート要素は”employees”です。employeesの子ノードは"employee"要素が二つだけ、のように見えます。しかし、NodeSampleを実行すると、employeesの子ノードは、テキストノード3つ、要素ノード2つの計5つと解釈されています。これは、どういうことでしょう。XMLでは、「空白」や「改行」などの文字も無視せず、そのままデータとして扱います。employees.xmlでは、人間が見やすいように、2行目"<employees>"と3行目"<employee>"の間に、改行文字と空白文字が記述されています。DOMでは、このデータを「最初の子ノード」「テキストノード」と解釈しているわけです。同様に、6行目"</employee>"と7行目"<employee>"の間の改行・空白文字は、「3番目の子ノード」、10行目"</employee>"と11行目"</employees>"の間の改行文字は「5番目の子ノード」と認識されます。XMLのインデント、空白、改行などには、充分注意する必要があります。

(実習課題1)

   XMLファイルを読み込み、ルート要素の名前、および文書タイプの名前を表示するプログラムを作成しなさい。

  <?xml version="1.0" encoding="ISO-8859-1"?>
  <!DOCTYPE web-app
      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
      "http://java.sun.com/dtd/web-app_2_3.dtd">
  <web-app>
  ...
  </webapp>

解答例はこちら

(実習課題2)

  employees.xmlファイルを読み込み、従業員の名前(employee要素の子要素nameの内容)の一覧を表示しなさい。
  ここでは、DocumentおよびNodeのみを使用してプログラムを書くこと
    ・要素の名前はgetNodeName()で取得する
    ・テキストの内容はgetNodeValue()で取得する

解答例はこちら

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp
  • シナジーマーケティング研究開発グループブログ