XMLマスターポイントレッスン
      ~ プロフェッショナル(アプリケーション開発)編 ~
第7回 最大の難関「総合問題」

インフォテリア株式会社  教育部 木村 達哉

これまで7回にわたり、「XMLマスター:プロフェッショナル(アプリケーション開発)」認定試験のポイントを解説してきました。いよいよ最終回となる今回は、同試験の最終セクション(セクション6)で出題される総合問題について説明します。

セクション6の出題範囲

  今回、ポイントを解説するセクション6は、「XMLマスター:プロフェッショナル(アプリケーション開発)」試験の最終セクションに当たります。ここで出題されるのは、以下の要素技術を組み合わせて使う際に必要な知識を問う、総合問題です。

XML
XML名前空間
DTD、XML Schema
XSLT
DOM、SAX

  また、設問の題材となるのは、実際の業務でもよくある処理ばかりです。例えば、次のような問題が考えられます。

何らかのXML仕様(例えば、「ContactXML※1などのXMLスキーマ)に準拠したXML文書を、DOMやSAXによって処理した結果を問う問題

※1  名前や住所、電話番号などのアドレス情報を記述するためのXML仕様。

実務データを記述したXML文書に対し、XSLTスタイルシートを適用した結果を問う問題

何らかの処理を施した後のXML文書が、特定のXML仕様(DTD、もしくはXML Schemaで書かれたXMLスキーマ)に従ったものであるかどうかを問う問題

名前空間を使用しているXML文書に何らかの処理を施した結果を問う問題

  こうした実務的な内容を扱うために、設問中で提示されるXML文書やJavaプログラムは、比較的長めのものになっています。したがって、それらのXML文書/Javaプログラムを正確に解読するには、ある程度の時間が必要です。セクション6のために余裕を残せるような時間配分も、試験対策の1つだと言えるでしょう。

  これらを踏まえ、以降では早速、例題とその解説に入ります。今回取り上げるのは、ContactXMLで書かれたXMLスキーマに従ったXML文書を、DOMによって処理した場合の結果を問う問題です。

●セクション6の出題例

  次の《DTD》※2に従ったXML文書を、《DOMによる処理》で示された方法によって処理した場合の出力結果(メソッドprintlnによる出力結果)として、正しいものを選択してください。

※2  一部、例題用に修正している。

《DTD》

<?xml version='1.0' encoding='UTF-8' ?>
<!ENTITY % unnamed "http://www.xmlns.org/2002/ContactXML">
 
<!ELEMENT ContactXML (ContactXMLItem+)>
 
<!ATTLIST ContactXML version(1.1)#REQUIRED
  creator CDATA #IMPLIED
  xmlns CDATA #FIXED 'http://www.xmlns.org/2002/ContactXML'>
<!ELEMENT ContactXMLItem (PersonName, Extension?)>
 
<!ATTLIST ContactXMLItem lastModifiedDate CDATA #IMPLIED>
<!ELEMENT PersonName (PersonNameItem+)>
 
<!ELEMENT PersonNameItem (FullName, FirstName?, LastName?)>
 
<!ATTLIST PersonNameItem xml:lang CDATA #REQUIRED>
<!ELEMENT FullName (#PCDATA)>
 
<!ATTLIST FullName pronunciation CDATA #IMPLIED>
<!ELEMENT FirstName (#PCDATA)>
 
<!ATTLIST FirstName pronunciation CDATA #IMPLIED>
<!ELEMENT LastName (#PCDATA)>
 
<!ATTLIST LastName pronunciation CDATA #IMPLIED>
<!ELEMENT Extension (ExtensionItem+)>
 
<!ELEMENT ExtensionItem (#PCDATA)>

《処理対象となるXML文書の条件》

《DTD》の定義に従っている
文書型宣言はない
ルート要素名(文書要素名)は「ContactXML」
要素と属性と文字データで構成されており、コメントやCDATAセクションなどは含まれていない
インデント(改行やタブなどの無意味な空白文字)は含まれていない

《DOMによる処理》

  以下のようにメソッドprocessXMLを呼び出すことにより、XML文書を処理します。

processXML(doc);

  このとき、変数docは、読み込んだXML文書のorg.w3c.dom.Documentインスタンスを参照しています。また、DOMパーサは名前空間を識別します。なお、コンパイル時のエラーはありません。

  メソッドprocessXMLの実装は、以下のとおりです。

public static void processXML(Document doc) {
  Node root = doc.getDocumentElement();
  NodeList list1 = root.getChildNodes();
 
  for(int i = 0; i &lt; list1.getLength(); i++) {
    NodeList list2 = list1.item(i).getChildNodes();
 
    for(int j = 0; j &lt; list2.getLength(); j++) {
      NodeList list3 = list2.item(j).getChildNodes();
 
      for(int k = 0; k &lt; list3.getLength(); k++) {
        NodeList list4 = list3.item(k).getChildNodes();
 
        for(int l = 0; l &lt; list4.getLength(); l++) {
          System.out.println(list4.item(l).getNodeValue());
        }
      }
    }
  }
}

選択肢
A.
常に実行時例外が発生する

B.
XML文書に要素FirstNameが記述されていない場合に、実行時例外が発生する

C.
実行時例外は発生しないが、要素FullNameの内容文字列を出力することができない

D.
実行時例外は発生せず、要素FullNameの内容文字列を出力することができる

解答
C

解説
  この問題を解く際には、最初に《DTD》を読み解く必要があります。ただし、例題の場合は《DTD》の記述量がやや多いため、いきなり頭から読み進めていくより、まずは要素型宣言のみを抽出してみるとよいでしょう。《DTD》から要素型宣言を抽出すると、以下のようになります。

<!ELEMENT ContactXML (ContactXMLItem+)>
<!ELEMENT ContactXMLItem (PersonName, Extension?)>
 
<!ELEMENT PersonName (PersonNameItem+)>
<!ELEMENT PersonNameItem (FullName, FirstName?, LastName?)>
<!ELEMENT FullName (#PCDATA)>
<!ELEMENT FirstName (#PCDATA)>
<!ELEMENT LastName (#PCDATA)>
 
<!ELEMENT Extension (ExtensionItem+)>
<!ELEMENT ExtensionItem (#PCDATA)>

  問題を解く手順としては、これを基に設問にあたり、必要に応じて他の属性リスト宣言を解読していくことになります。しかし、ここで《DOMによる処理》を見てみると、メソッドprocessXML内の記述にXMLの属性を操作する処理はないことに気づくはずです。したがって、この設問では、属性リスト宣言を無視してよいということになります(選択肢を眺めてみても、属性の処理について問うようなものはありません)。

  また、《DTD》の2行目に記述されている「unnamed」という名前のパラメータ実体は、実際にはほかから参照されていないため、これも無視することが可能です。

  さらに、《DTD》の6行目に注目してください。ここには、属性リスト宣言として「http://www.xmlns.org/2002/ContactXML」という値が記述されていますが、これはXML文書の名前空間の指定に相当します。

  提示された《DTD》の要素型宣言に従ったXML文書(属性リスト宣言は無視する)の例は、以下のようになります。

<ContactXML xmlns="http://www.xmlns.org/2002/ContactXML">【R】
  <ContactXMLItem>【+】
    <PersonName>【1】
      <PersonNameItem>【+】
        <FullName>山田 太郎</FullName>【1】
        <FirstName>太郎</FirstName>【?】
        <LastName>山田</LastName>【?】
      </PersonNameItem>
    </PersonName>
    <Extension>【?】
      <ExtensionItem>拡張情報</ExtensionItem>【+】
    </Extension>
  </ContactXMLItem>
</ContactXML>

  なお、【R】はルート要素を表し、【+】や【1】は、《DTD》で指定された要素の出現回数を表しています。また、《処理対象となるXML文書の条件》にもあるように、処理するXML文書にはインデントは含まれていません。

  以上を踏まえ、メソッドprocessXMLを読み解くと、次のようになります。

  まず最初に行っているのは、XML文書のルート要素を取得し、変数rootに格納する処理です。続いて、4つの変数(変数list1~list4)を利用してルート要素から順に子ノードを取り出し、最終的に変数list4に格納された各ノードの値(nodeValue)を出力しています。

  では、変数list1~list4に格納されるノードは、具体的にどのノードなのかを確認しておきましょう。

変数list1:ルート要素の子ノード(要素ContactXMLItem)
変数list2:要素ContactXMLItemの子ノード(要素PersonName、または要素Extension)
変数list3:要素PersonName(または要素Extension)の子ノード(要素PersonNameItem、または要素ExtensionItem)
変数list4:要素PersonNameItem(または要素ExtensionItem)の子ノード(要素PersonNameItemの場合は、要素FullName/FirstName/LastName。要素ExtensionItemの場合は、テキスト・ノード)

  したがって、変数list4に格納されるノードは、以下のいずれかになります。

要素FullName
要素FirstName
要素LastName
要素ExtensionItemが持つテキスト・ノード

  これらの要素やテキスト・ノードに対して、値(nodeValue)の取得を実行(すなわち、メソッドgetNodeValueを実行)すると、どのような結果になるのでしょうか。実は、要素に対してメソッドgetNodeValueを実行した場合、常にnullが返されます。DOMでは、要素は直接値を持たず、その子ノードに当たるテキスト・ノードが値を持つのです。

  したがって、テキスト・ノードに対してメソッドgetNodeValueを実行した場合にのみ、null以外の値を取得することができます。

  以上を踏まえ、設問の選択肢を検証してみましょう。

選択肢A:要素に対して、メソッドgetNodeValueを実行した場合はnullが返され、テキスト・ノードに対して実行した場合はそのテキスト値を取得できるため、実行時例外は発生しない。したがって、選択肢Aは誤り

選択肢B:XML文書中、要素FirstNameが記述されているか否かにかかわらず、メソッドprocessXML内のfor文はすべて正常に実行することができるので、選択肢Bは誤り

選択肢D:要素に対してメソッドgetNodeValueを実行しても、値は取得できないため、選択肢Dは誤り

  よって、選択肢Cが正解となります。

  この設問は、「XML文書が提示されない、XMLの問題」です。つまり、提示されたXMLスキーマに従ったXML文書を自分の頭の中で想像し、さまざまな可能性を考えながらJavaプログラム(DOMによる処理)を読み解く必要があります。限られた試験時間内では大変な作業かもしれませんが、こうした思考プロセスは、まさに実践的なものだと言えるでしょう。

  こういったことから、「XMLマスター:プロフェッショナル(アプリケーション開発)」認定試験では、単にXMLを知っているだけでなく、それをさまざまなプログラムとともに利用したことがある方のほうが有利かもしれません。つまり、「XMLマスター:プロフェッショナル(アプリケーション開発)」認定試験の最大のポイントは「自分でXMLを使ってみること」だと言えそうです。

  以上、本連載では7回にわたり、「XMLマスター:プロフェッショナル(アプリケーション開発)」認定試験のポイントを解説してきました。これまで説明してきたように、実践的な色彩の強い試験ですが、すでに受験した方からは、「難易度は高いものの、問題を解いていて面白かった」といった意見も聞かれるようです。これから受験する方も、楽しむつもりで気軽にチャレンジしてみてはいかがでしょうか。


ページトップへ▲

XMLマスターポイントレッスン ~ プロフェッショナル(アプリケーション開発)編 ~ 記事一覧へ戻る

HOMEへ戻る