Игнорирование DTD при анализе XML
Как игнорировать объявление DTD при анализе файла с помощью библиотеки XOM xml. Мой файл имеет следующую строку:
<?xml version="1.0"?>
<!DOCTYPE BlastOutput PUBLIC "-//NCBI//NCBI BlastOutput/EN" "NCBI_BlastOutput.dtd">
//rest of stuff here
И когда я пытаюсь построить() мой документ, я получаю исключение filenotfound для файла DTD. Я знаю, что у меня нет этого файла, и мне все равно, так как его можно удалить при использовании 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();
При удалении DTD-строки из исходного XML файла я могу успешно проанализировать его, но это не вариант в конечной производственной системе.
Ответы
Ответ 1
Предпочтительным решением было бы реализовать EntityResolver, который перехватывает запросы для DTD и перенаправляет их во встроенную копию. если ты
- не имеют доступа к DTD и
- абсолютно уверены, что вам это не понадобится (помимо проверки, он может также объявлять объекты символов, которые используются в документе) и
- вы используете реализацию XML Parser Xerces
вы можете отключить выборку DTD, установив соответствующую функцию SAX. В 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);
Ответ 2
Согласно их документации, это способ анализа документа без какой-либо проверки.
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
еще одно исключение: ValidityException