JDK 1.6 中验证失败,JDK 1.7 中验证成功。

3

我在使用一个非常基础的XSD验证xml时遇到了一个奇怪的问题。JDK 1.6和JDK 1.7的行为不同...

这是我的模式:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Salaries" type="SalariesType">
    <xs:unique name="Salary-Ctrl">
      <xs:selector xpath="Salary" />
      <xs:field xpath="@institutionIDRef" />
      <xs:field xpath="Code" />
    </xs:unique>
  </xs:element>
  <xs:complexType name="SalariesType">
    <xs:sequence>
      <xs:element name="Salary" type="SalaryType" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="SalaryType">
    <xs:sequence>
      <xs:element name="ValidAsOf" type="xs:date" minOccurs="0" />
      <xs:element name="Code" type="xs:string" minOccurs="0" />
      <xs:element name="AnnualBasis" type="xs:string" />
    </xs:sequence>
    <xs:attribute name="institutionIDRef" type="xs:string" use="required" />
  </xs:complexType>
</xs:schema>

以下是我的XML代码:

<Salaries>
  <Salary institutionIDRef="someID">
    <AnnualBasis>someContent</AnnualBasis>
  </Salary>
</Salaries>

为了进行验证,我使用了这个简单的程序:

SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(new SAXSource(new InputSource(new ByteArrayInputStream(xsd.getBytes()))));
Validator validator = schema.newValidator();

validator.validate(new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes()))));
System.out.println("Validated !");

如果我使用JDK 1.7运行这段代码,就不会出现错误,XML将被验证(使用JDK 1.5也是如此)。但是在JDK 1.6中,我会遇到以下异常:

Exception in thread "main" org.xml.sax.SAXParseException: Not enough values specified for <unique> identity constraint specified for element "Salaries".
    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:423)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3188)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$ValueStoreBase.endValueScope(XMLSchemaValidator.java:3463)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endValueScopeFor(XMLSchemaValidator.java:1479)
    at com.sun.org.apache.xerces.internal.impl.xs.identity.Selector$Matcher.endElement(Selector.java:235)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleEndElement(XMLSchemaValidator.java:2169)
    at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.endElement(XMLSchemaValidator.java:824)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.endElement(ValidatorHandlerImpl.java:565)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2939)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:647)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.validate(ValidatorHandlerImpl.java:700)
    at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:97)
    at javax.xml.validation.Validator.validate(Validator.java:127)
    at ch.Test.main(Test.java:53)

我该如何让验证器在JDK 1.6中接受这个呢?

谢谢并致以最好的问候。

1个回答

2

看起来是模式处理器中的一个错误。解决方案:使用更可靠且不依赖于JDK版本的模式处理器,如Apache Xerces或Saxon-EE。

JDK中XML软件的漏洞似乎永远得不到修复,您可能需要等待几年才能获得错误报告的答复。我强烈怀疑JDK发布时没有运行所有W3C XML符合性测试。使用第三方库通常更加可靠。


你好,感谢回复。不幸的是,我无法轻松地完成这个任务,因为验证是在调用 Web 服务时进行的(实际上是封送失败)。我猜想简单的解决方案是升级到 JDK 1.7 并在我的 JavaEE6 环境中使用 -source 1.6 选项... - ctabin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接