目次へ

解答例 - 実習課題1 - 6.DTD(DocumentType)

(実習課題1)

XMLパーサには、DTDを解読した上でXML文書がDTDに沿った構造になっているか解析するvalidate機能が提供されています。ただし、アプリケーションで使用するXMLの構造があらかじめ決まっている場合、パーサがDTDを読み取る処理がオーバーヘッドになります。そこで、以下のコンソールプログラムを作成しなさい。

  • 引数に与えられたXML文書が、以下のDTDで表される構造になっているか、判定するプログラム
  • 与えられたXMLが以下の条件を満たすときのみ、DTDに沿ったXMLファイルかどうか、解析する。解析結果は標準出力に表示する。
    • ルート要素 :person
    • 公開識別子: -//Four Dimensional Data, Inc.//DTD DOM Example 1.0//EN
    • システム識別子: http://www.techscore.com/tech/Java/DOM/DOMExample.dtd
  • 上記以外のDTDが指定されている場合、エラーメッセージを標準エラーに出力し、プログラムを終了する。
  • XMLパーサのvalidate機能を使用しない。
     Java 1.4付属のパーサを使用する場合、デフォルトでXMLパーサのvalidate機能は使用できないようになっています。また、以下のようにして、validate機能を使用しないように設定することが可能です。
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(false);
    
  • 解析するXML文書にコメントやエンティティは含まれないものとしてよい。

  • DTDは以下の通り。
    <!-- person要素がルート要素となる -->
    <!ELEMENT person (name,age,license*)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT license (#PCDATA)>
    ※"http://www.techscore.com/tech/Java/DOM/DOMExample.dtd"が参照できる環境でプログラムを実行する必要があります。

解答例

package com.techscore.dom.chapter6.exercise1;

import java.io.File;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * DtdValidator.java
 * 
 * TECHSCORE Java XML DOM XSLT 6章 実習課題1
 * 
 * Copyright (c) 2004 Four-Dimensional Data, Inc.
 */

public class DtdValidator {

    private static final String[] ELEMENT_NAMES = {"name", "age", "license"};

    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            System.out.println("引数にXML文書ファイルを指定してください");
            return;
        }

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(false);

        Document document = factory.newDocumentBuilder()
                .parse(new File(args[0]));

        DocumentType dtd = document.getDoctype();
        if(dtd == null){
            System.err.println("DOCTYPE宣言がありません");
            return;
        }

        // XMLファイルを解析するかどうか判定する
        Element person = document.getDocumentElement();
        if ((!"person".equals(dtd.getName()))
                || (!"-//Four Dimensional Data, Inc.//DTD DOM Example 1.0//EN".equals(dtd.getPublicId()))
                || (!"http://www.techscore.com/tech/Java/DOM/DOMExample.dtd".equals(dtd.getSystemId()))) {
            System.err.println("DTDが規定されたものではありません");
            return;
        }

        int idx = 0;
        NodeList nodeList = person.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE) {
                if (!ELEMENT_NAMES[Math.min(idx++, 2)].equals(nodeList.item(i)
                        .getNodeName())) {

                    System.err.println("このXML文書は"
                            + "『<!ELEMENT person (name,age,license*)>』"
                            + "という指定に従っていません");
                    return;

                } else if (nodeList.item(i).hasChildNodes()) {

                    NodeList childList = nodeList.item(i).getChildNodes();
                    for (int j = 0; j < childList.getLength(); j++) {
                        if (childList.item(j).getNodeType() != Node.TEXT_NODE) {
                            System.err.println("このXML文書は" + "『<!ELEMENT "
                                    + nodeList.item(i).getNodeName()
                                    + " #PCDATA』" + "という指定に従っていません");
                            return;
                        }
                    }
                }
            } else if (nodeList.item(i).getNodeType() == Node.TEXT_NODE) {
                if (!nodeList.item(i).getNodeValue().matches("\\s*")) {
                    System.err.println("このXML文書には、不正な文字列が含まれています");
                    return;
                }
            }
        }
        System.out.println("このXML文書は規定のDTDに従っています");
    }

}

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp