【问题标题】:Java XML Parse/Validation Error HandlingJava XML 解析/验证错误处理
【发布时间】:2013-11-03 13:00:22
【问题描述】:

我正在尝试用 Java 编写一些东西,它接收 XML 字符串并根据 XSD 模式对其进行验证,并对一些简单的常见错误进行自动错误处理,并输出固定的 XML 字符串。

我遇到了 Validator.validate() 函数的 SAX ErrorHandler 接口,但这似乎主要用于报告异常,我不知道如何从中修改 XML,除了获取线路/column number 这将是非常繁琐的解决问题。

我还发现了 Validator.validate() 函数,它具有源和结果,并返回增强的 XML,据我所知,它只是填充具有默认值的缺失属性,这是我需要做的一部分。

但是我还需要一些东西,比如修复缺少的开始或结束标签,纠正一个字母拼错的标签,诸如此类。有这么多“处理程序”接口(@98​​7654324@、ContentHandlerEntityResolver),我不确定要深入研究哪些接口,所以如果有人能指出我正确的方向,那就太好了(我不需要详细的代码示例)。

我也不确定XMLReader 是如何适应这一切的。

【问题讨论】:

  • 请不要以一大段文字发帖,读起来有些痛苦。

标签: java xml validation xml-parsing sax


【解决方案1】:

要处理错误,您必须实现接口ErrorHandler 或扩展DefaultHandler 辅助类并重新定义error 方法。这就是验证错误所调用的方法。如果您想更精确,我认为您将不得不分析错误消息。我认为 SaX 不会为您提供使错误易于修复的功能。

顺便说一句,请注意,要针对 XSD 进行验证,您不应使用方法 setValidating。请参阅下面的代码。

setValidating 方法的 Java 文档 (1.7) 说:

请注意,这里的“验证”是指 XML 建议中定义的验证解析器。换句话说,它本质上只是控制 DTD 验证。 (JAXP 1.2 中定义的两个遗留属性除外。)

要使用现代模式语言(如 W3C XML Schema 或 RELAX NG)而不是 DTD,您可以将解析器配置为非验证解析器,方法是将 setValidating(boolean) 方法保留为 false,然后使用 setSchema(Schema) 方法将架构与解析器相关联。

import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
// ...
public static void main(String args[]) throws Exception {
        if (args.length == 0 || args.length > 2) {
            System.err.println("Usage: java Validator <doc.xml> [<schema.xsd>]");
            System.exit(1);
        }
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.    W3C_XML_SCHEMA_NS_URI);
        String xsdpath = "book.xsd";
        if (args.length == 2) {
            xsdpath = args[1];
        }
        Schema s = sf.newSchema(new File(xsdpath));
        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(false);
        factory.setNamespaceAware(true);
        factory.setSchema(s);
        
        XMLReader parser = factory.newSAXParser().getXMLReader();
        parser.setFeature("http://xml.org/sax/features/namespaces", true);
        parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);

        PrintStream out = new PrintStream(System.out, true, "UTF-8");
        parser.setContentHandler(new MyHandler(out));
        parser.setErrorHandler(new DefaultHandler());
        parser.parse(args[0]);
    }
}

【讨论】:

  • 感谢代码和关于 setValidating 的部分,我不知道。
【解决方案2】:

我使用DocumentBuilderFactorysetValidating(true) 来生成一个XML 验证解析器的实例(即DocumentBuilder)。

请注意,验证和非验证 XML 解析器都会验证 XML 是否“格式正确”(例如结束标记等)。 “验证”是指检查 XML 是否符合 DTD 或模式。

【讨论】:

  • setValidating(true) 专门针对 DTD 而不是 W3C XML 模式进行验证。另请注意,模式可以是 DTD、XSD、... DTD、W3C XML 模式、Relax NG、Schematron 都是模式语言。
猜你喜欢
  • 2017-07-04
  • 2016-02-07
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多