5

在 java 1.6 中使用 dom4j DOMDocument 来提供 validator.validate(DOMSource) 失败(xsi:noNamespaceSchemaLocation 不允许出现在根元素中),在 1.5 中有效

我发现以下问题非常棘手(好吧,这是轻描淡写的) - 任何见解都会受到赞赏。目前似乎最好的想法是放弃 dom4j 以支持例如 XOM (http://stackoverflow.com/questions/831865/what-java-xml-library-do-you-recommend-to-replace-dom4j)。

我一直在验证从 dom4j 'new DOMDocument()' 创建的内存 XML - 但这不适用于 Java 6。

以下对 dom4j (1.6.1) DOMDocument 派生的 DOMSource 的 validate(source) 调用适用于 Java 1.5.x,但在 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() 还用于将 xsi:noNamespaceSchemaLocation 属性添加到根节点,即:xsi:noNamespaceSchemaLocation="http://localhost:8080/integration/xsd/fqlResponseSchema-2.0.xsd"

异常如下:

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)

这是 XML 的开头 - 在禁用对 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>

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">
................

所以我的根元素被拒绝了,因为它包含一个 xsi:noNamespaceSchemaLocation 属性。并且架构本身并没有将其指定为我的根元素的有效属性?

在这一点上,在我看来,我需要为这项任务放弃 dom4j 并切换到其他解决方案之一,例如此处概述的:

但无论如何我想知道我做错了什么!

提前致谢。

4

2 回答 2

3

我遇到了同样的问题,我在以下位置找到了以下文档

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

针对文档指定的架构进行验证

一些文档指定了他们希望验证的架构,通常使用 xsi:noNamespaceSchemaLocation 和/或 xsi:schemaLocation 属性,如下所示:

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

如果您在创建模式时没有指定 URL、文件或源,那么 Java 语言会创建一个在被验证的文档中查找它应该使用的模式。例如:

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

但是,通常这不是您想要的。通常文档消费者应该选择模式,而不是文档生产者。此外,这种方法仅适用于 XSD。所有其他模式语言都需要明确指定的模式位置。

于 2012-07-30T16:09:01.117 回答
0

原因似乎是正在创建和使用非命名空间感知的 JAXP SAXParser(请参阅链接)。

以及我在www.edankert.com找到的不同库的解决方案。

于 2013-01-08T18:01:38.407 回答