【问题标题】:JAXB Validator does not detect syntax errors?JAXB Validator 不检测语法错误?
【发布时间】:2014-10-24 04:41:53
【问题描述】:

我想在解组之前使用它的 xsd 验证一个 xml 文件。

代码如下:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(xsdFilePath);
Validator validator = schema.newValidator();
validator.setErrorHandler(new MyValidationErrorHandler());
validator.validate(new StreamSource(xmlFilePath));

我发现当一个 xml 元素没有关闭时,Validator 未能将其记录为错误,但 UnMarshaller 识别到这一点并抛出“发现以元素开头的无效内容..”错误。

我希望验证和解组/编组是不同的操作。

有没有办法让验证器检测 xml 文件中的此类语法错误?

【问题讨论】:

    标签: java xml validation jaxb


    【解决方案1】:

    你必须区分两件事:

    1. XML 文档的基本语法
    2. 文档符合 XML 模式

    如果基本语法不正确,那么就没有文档可以调查其元素结构、属性存在、价值符合方面等等。

    恐怕你必须同时捕获这两种异常。

    但是,您可以在一个解组操作中处理所有事情:

    JAXBContext payloadContext = JAXBContext.newInstance("generated");
    Unmarshaller unmarshaller = payloadContext.createUnmarshaller();
    unmarshaller.setSchema(schemaFactory.newSchema(... )););
    unmarshaller.setEventHandler( new ValidationEventHandler(){
        public boolean handleEvent(ValidationEvent event) {
                System.out.println( "Event! " + event );
                return true;
        }
    } );
    

    稍后

    要仅进行验证,您仍然需要进行解析,但如果您没有 JAXB-ish 类,则可以使用 JAXP:

    static class Handler implements ErrorHandler {
      public void error(SAXParseException exception){
        System.out.println( "error: " + exception.getMessage() );
      }
      public void fatalError(SAXParseException exception){
        System.out.println( "fatal: " + exception.getMessage() );
      }
      public void warning(SAXParseException exception){
        System.out.println( "warning: " + exception.getMessage() );
      }
    }
    
    Handler handler = new Handler();
    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    parser.setErrorHandler( handler );
    try {
        Document document = parser.parse(new File("test.xml"));
        SchemaFactory factory =
          SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Source schemaFile = new StreamSource(new File("test.xsd"));
        Schema schema = factory.newSchema(schemaFile);
        Validator validator = schema.newValidator();
        validator.setErrorHandler( handler );
        try {
          validator.validate(new DOMSource(document));
        } catch (SAXException e) {
          // ...
          System.out.println( "VAlidation error" );
        }
    } catch (SAXParseException e) {
        // syntax error in XML document     
        System.out.println( "Syntax error" );
    }
    

    对于验证,设置处理程序不会抛出 ParseException,因此其中之一是多余的。

    【讨论】:

    • 我想分别保持验证和解组的原因是因为我希望验证尽可能通用,而不是对 JAXBContext 有太多依赖,因为这将在多个地方重用以验证 xml文件。我想要一个验证 API,它可以报告 xml 文件中的语法/解析错误以及它的 Schema 合规性错误。
    猜你喜欢
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2014-07-28
    相关资源
    最近更新 更多