Shammer's Philosophy

My private adversaria

JAXPでXercesを使用する

Xercesは、JAXP にも対応している。

これまでは、直接Xercesのクラスを直接生成する方法をとってきたが、

これだとXMLを扱うライブラリを変更した場合にはソースコードの書き換えが必要になる。

XMLを扱うライブラリに依存した形になっているので、これを改めてJAXP を使用した方が

Xercesへの依存度を下げられる場合がある。



JAXPとは、XML文書を解析したり変形したりするための共通APIである。

しかし、、、若干気になることが。WikiPediaでは、Java API for XML Processing の略となっているが、

本家の情報、


          The Java Community Process(SM) Program - JSRs: Java Specification Requests - detail JSR# 5


ではJava API for XML Parsing となっている。

これは、本家の情報に従うべきだろう。

どちらにせよ、DOMやSAXのAPIはこの仕様に則って定められているらしい。



実際に、JAXPを利用してソースを書くとこうなる。


import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import share.util.MyErrorHandler;
/**
 * SimpleParseJAXP.
 */
public class SimpleParseJAXP 
{
    public static void main(String[]args)
    {
        if( args.length != 1 ) {
            System.err.println("Usage: java SimpleParseJAXP <filename>");
            System.exit(1);
        }
        try {
            // Create Document Builder Factory
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(true);
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            builder.setErrorHandler(new MyErrorHandler());
            Document document = builder.parse(args[0]);
        }
        catch( javax.xml.parsers.ParserConfigurationException e ){
            e.printStackTrace();
        }
        catch( org.xml.sax.SAXException e ){
            e.printStackTrace();
        }
        catch( java.io.IOException e ){
            e.printStackTrace();
        }
    }
}


Abstract Factory パターンが利用されているようだ。
上記のように書いておけば、ParserにXercesを使わなくなったとしても
その変更を気にせず処理を実行できる。



ポイントは次のところだろうか。

  • DocumentBuilderFactory.setValidating(boolean)で、XML妥当性検証の可否を指定
  • DocumentBuilderFactory.setNamespaceAware(boolean)で、名前空間の使用可否を指定
  • DocumentBuilderFactory.newDocumentBuilder()メソッドでDocumentBuilderを生成

XML Schema 文書の検証をする場合は、setValidating(true)と、

setNamespaceAware(true)は必須になるだろうな。