所以我有大量的XML文件。多年来,他们造成了麻烦,因为写这些人的人手工完成,所以错误自然而然地发生了。我们现在应该在尝试使用这些XML文件时验证它们并提供有关错误的反馈。
我正在使用SAX解析器并获取错误列表。
以下是我的代码
BookValidationErrorHandler errorHandler = new BookValidationErrorHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
SchemaFactory schemaFactory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
factory.setSchema(schemaFactory.newSchema(
new Source[] {new StreamSource("test.xsd")}));
javax.xml.parsers.SAXParser parser = factory.newSAXParser();
org.xml.sax.XMLReader reader = parser.getXMLReader();
reader.setErrorHandler(errorHandler);
reader.parse(new InputSource("bad.xml"));
前几个错误始终是:
行号:2:文档无效: 没找到语法。行号:2: 文件根元素“信用”,必须 匹配DOCTYPE根“null”。
我们不可能去编辑需要检查的数千个XML文件。
有什么我可以轻松添加到源的前面来防止这种情况吗?有没有办法告诉解析器忽略这些与DTD相关的错误?甚至不确定语法是什么意思。我有点理解第二个意味着什么。
答案 0 :(得分:7)
设置setValidating(true)
请求DTD验证,如果不存在DTD则导致失败。如果您只想要架构验证而不是DTD验证,请使用setValidating(false)
。来自the Javadoc for setValidating()
:
要使用现代架构语言(如W3C XML Schema或RELAX NG而不是DTD),可以将
setValidating(boolean)
方法设为false,将解析器配置为非验证解析器,然后使用{{1}将模式关联到解析器的方法。
答案 1 :(得分:0)
public class CustomResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.equals("http://namespace1.example.com/ex1")) {
return new InputSource("xsd_for_namespace1_path"));
} else if (systemId.equals("http://namespace2.example.com/ex2")) {
return new InputSource("xsd_for_namespace2_path"));
} else if (systemId.equals("http://namespace3.example.com/ex3")) {
return new InputSource("xsd_for_namespace3_path"));
}
return null;
}
}
我也禁用了setValidating()属性。这是我的解析器配置:
SAXParserFactory saxpf = SAXParserFactory.newInstance();
saxpf.setNamespaceAware(true);
saxpf.setSchema(getSchema());
saxpf.setValidating(false);
SAXParser saxParser = saxpf.newSAXParser();
saxParser.getParser().setEntityResolver(new XSDResolver());
方法getSchema()实例化一个Schema,就像在代码中实现一样,但是有更多的源代码。
我希望它可以帮助那些发现同样错误的人。
答案 2 :(得分:0)
如果您正在使用符合JAXP的解析器并且正确配置as per the Oracle documentation,您仍然可以使用验证解析器而不需要在解析器中预设架构:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
SAXParser saxParser = spf.newSAXParser();
// Important step next: Tell the parser which XML schema-definition language to expect:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
// Now when we parse a file without a DTD, we no longer get an error
// (as long as an XSD schema is defined in the file):
saxParser.parse(source, handler);