解析XML时忽略DTD

如何在使用XOM xml库解析文件时忽略DTD声明。 我的文件有以下行:

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

当我尝试构建()我的文档时,我得到了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行,我可以成功解析它,但这不是最终生产系统中的一个选项。


首选的解决方案是实现一个拦截DTD请求并将其重定向到嵌入式副本的EntityResolver。 如果你

  • 无法访问DTD和
  • 绝对确定你不需要它(除了验证之外它还可以声明文档中使用的字符实体)和
  • 您正在使用Xerces XML解析器实现
  • 您可以通过设置相应的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);
    

    根据他们的文档,这是解析文档没有任何验证的方式。

    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

    链接地址: http://www.djcxy.com/p/5947.html

    上一篇: Ignoring DTD when parsing XML

    下一篇: Filter \n character from inputstream