Using dom4j DOMDocument to feed validator.validate(DOMSource) fails in java 1.6 (xsi:noNamespaceSchemaLocation is not allowed), works in 1.5

眉间皱痕 提交于 2019-12-22 08:08:16

问题


Using dom4j DOMDocument to feed validator.validate(DOMSource) fails in java 1.6 (with xsi:noNamespaceSchemaLocation is not allowed to appear in root element), works in 1.5

I'm finding the following problem quite intractable (OK, that's an understatement) - any insights will be appreciated. Currently it seems like the best idea is to drop dom4j in favour of e.g. XOM (http://stackoverflow.com/questions/831865/what-java-xml-library-do-you-recommend-to-replace-dom4j).

I've been validating in memory XML created from dom4j 'new DOMDocument()' - but this will not work with Java 6.

The following call to validate(source) of a dom4j (1.6.1) DOMDocument derived DOMSource works with Java 1.5.x but fails with Java 1.6.x:

public void validate() throws Exception {
    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    schemaFactory.setErrorHandler(null);
    Schema schemaXSD = schemaFactory.newSchema(new URL(getSchemaURLString()));
    Validator validator = schemaXSD.newValidator();
    DOMSource source = new DOMSource(getDocument());
    validator.validate(source);
}

getSchemaURLString() is also used to add the xsi:noNamespaceSchemaLocation attribute to the root node, i.e.: xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd"

The exception follows:

Exception:  org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute 'xsi:noNamespaceSchemaLocation' is not allowed to appear in element 'specialfields'.;                
complex-type.3.2.2: Attribute 'xsi:noNamespaceSchemaLocation' is not allowed to appear in element 'specialfields'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:417)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3182)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(XMLSchemaValidator.java:2659)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2066)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.beginNode(DOMValidatorHelper.java:273)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:240)
at com.sun.org.apache.xerces.internal.jaxp.validation.DOMValidatorHelper.validate(DOMValidatorHelper.java:186)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:104)
at javax.xml.validation.Validator.validate(Validator.java:127)

Here's the start of the XML - generated after disabling the call to validator.validate(source):

<?xml version="1.0" encoding="utf-8"?> 
<meetings xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
.............
</meetings>

And of the XSD:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xs:element name="meetings">
    <xs:complexType>
      <xs:choice>
    <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="1" ref="summary" />
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="meeting" />
        </xs:sequence>
        <xs:element ref="error" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="summary">
................

So my root element is being rejected because it contains a xsi:noNamespaceSchemaLocation attribute. And the schema itself does not specify that as a valid attribute of my root element?

At this point it seems to me that I need to give up on dom4j for this task and switch to one of the other solutions, for example as outlined here:

But I'd like to know what I've done wrong at any rate!

Thanks in advance.


回答1:


I had the same issue, and I found the following documentation at

http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi/index.html

Validate against a document-specified schema

Some documents specify the schema they expect to be validated against, typically using xsi:noNamespaceSchemaLocation and/or xsi:schemaLocation attributes like this:

<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">  
 ...

If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 
Schema schema = factory.newSchema();

However, normally this isn't what you want. Usually the document consumer should choose the schema, not the document producer. Furthermore, this approach works only for XSD. All other schema languages require an explicitly specified schema location.




回答2:


The reason seems to be that non-namespace aware JAXP SAXParser is being created and used (see Link).

And solution for different libs I found at www.edankert.com.



来源:https://stackoverflow.com/questions/5080784/using-dom4j-domdocument-to-feed-validator-validatedomsource-fails-in-java-1-6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!