13

XOM xml ライブラリを使用してファイルを解析するときに、DTD 宣言を無視するにはどうすればよいですか。私のファイルには次の行があります:

<?xml version="1.0"?>
<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "NCBI_BlastOutput.dtd">
//rest of stuff here 

そして、ドキュメントを build() しようとすると、DTD ファイルに対して filenotfound 例外が発生します。私はこのファイルを持っていないことを知っていますし、気にもしていません。XOM を使用している場合、どうすればこのファイルを削除できますか?

コード スニペットを次に示します。

public BlastXMLParser(String filePath) {
    Builder b = new Builder(false);
     //not a good idea to have exception-throwing code in constructor
    try {

        _document = b.build(filePath);
    } catch (ParsingException ex) {
        Logger.getLogger(BlastXMLParser.class.getName()).log(Level.SEVERE,"err", ex);
    } catch (IOException ex) {
        //
    }

private Elements getBlastReads() {
    Element root = _document.getRootElement();
    Elements rootChildren = root.getChildElements();

    for (int i = 0; i < rootChildren.size(); i++) {
        Element child = rootChildren.get(i);
        if (child.getLocalName().equals("BlastOutput_iterations")) {

            return child.getChildElements();
        }
    }

    return null;
}
}

この行で NullPointerException を取得します。

Element root = _document.getRootElement();

ソース XML ファイルから DTD 行を削除すると、正常に解析できますが、これは最終的な運用システムのオプションではありません。

4

3 に答える 3

17

推奨される解決策は、DTDの要求をインターセプトし、これらを埋め込みコピーにリダイレクトするEntityResolverを実装することです。もし、あんたが

  1. DTDにアクセスできず、
  2. あなたがそれを必要としないことを絶対に確信しています(検証は別として、それはまた文書で使用される文字エンティティを宣言するかもしれません)そして
  3. XercesXMLパーサーの実装を使用しています

対応するSAX機能を設定することにより、DTDのフェッチを無効にすることができます。XOMでは、次のようにXMLReaderをBuilderコンストラクターに渡すことでこれが可能になります。

import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

...

XMLReader xmlreader = XMLReaderFactory.createXMLReader();
xmlreader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
Builder builder = new Builder(xmlreader);
于 2011-11-10T15:32:26.917 に答える
-6

ドキュメントによると、これは検証なしでドキュメントを解析する方法です。

try {
  Builder parser = new Builder();
  Document doc = parser.build("http://www.cafeconleche.org/");
}
catch (ParsingException ex) {
  System.err.println("Cafe con Leche is malformed today. How embarrassing!");
}
catch (IOException ex) {
  System.err.println("Could not connect to Cafe con Leche. The site may be down.");
}

XML スキーマを検証したい場合は、次のように呼び出す必要がありますnew Builder(true)

try {
  Builder parser = new Builder(true);
  Document doc = parser.build("http://www.cafeconleche.org/");
}
catch (ValidityException ex) {
  System.err.println("Cafe con Leche is invalid today. (Somewhat embarrassing.)");
}
catch (ParsingException ex) {
  System.err.println("Cafe con Leche is malformed today. (How embarrassing!)");
}
catch (IOException ex) {
  System.err.println("Could not connect to Cafe con Leche. The site may be down.");
}

さらに別の例外がスローされる可能性があることに注意してください。ValidityException

于 2011-11-10T14:52:59.680 に答える