java xml 验证 JDK 1.5 JDK 1.6 区别

发布于 2024-08-03 16:36:56 字数 2631 浏览 6 评论 0原文

我在 Java xml 验证方面遇到问题。

我有以下 xsd:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="TEST">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="LAST_NAME">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:minLength value="1" />
              <xsd:maxLength value="30" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="FIRST_NAME">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:minLength value="1" />
              <xsd:maxLength value="20" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="DOB" nillable="true" type="xsd:date" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

和 xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<TEST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <LAST_NAME>Lastname</LAST_NAME>
  <FIRST_NAME>Firstname</FIRST_NAME>
  <DOB xsi:nil="true"/>
</TEST>

我的验证器的(简化的)代码:

boolean valid=true;
try {
    Source schemaSource = new StreamSource(xsdInputStream);
    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = parser.parse(xmlInputStream);
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    Schema schema = factory.newSchema(schemaSource);

    Validator validator = schema.newValidator();
    try {
        validator.validate(new DOMSource(document));
    } catch (SAXException e) {
        logger.log(Level.INFO, e.getMessage(), e);
        valid = false;
    }

} catch( Exception ex ) {
    logger.log(Level.SEVERE, ex.getMessage(), ex);
    valid=false;
}

测试程序在 JDK 1.5 和 JDK 1.6 中具有不同的行为。该xml在JDK 1.5中有效,但在JDK 1.6中无效。错误信息如下:

Element 'DOB' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xsi:nil' was found.

哪个JDK是正确的?如何更改 xml/xsd 使其在两者中都有效?

I have a problem with Java xml validation.

I have the following xsd:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="TEST">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="LAST_NAME">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:minLength value="1" />
              <xsd:maxLength value="30" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="FIRST_NAME">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:minLength value="1" />
              <xsd:maxLength value="20" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:element>
        <xsd:element name="DOB" nillable="true" type="xsd:date" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

and xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<TEST xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <LAST_NAME>Lastname</LAST_NAME>
  <FIRST_NAME>Firstname</FIRST_NAME>
  <DOB xsi:nil="true"/>
</TEST>

The (simplified) code of my validator:

boolean valid=true;
try {
    Source schemaSource = new StreamSource(xsdInputStream);
    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = parser.parse(xmlInputStream);
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    Schema schema = factory.newSchema(schemaSource);

    Validator validator = schema.newValidator();
    try {
        validator.validate(new DOMSource(document));
    } catch (SAXException e) {
        logger.log(Level.INFO, e.getMessage(), e);
        valid = false;
    }

} catch( Exception ex ) {
    logger.log(Level.SEVERE, ex.getMessage(), ex);
    valid=false;
}

The testprogram has a different behavior in JDK 1.5 and JDK 1.6. The xml is valid in JDK 1.5 but invalid in JDK 1.6. The error message is the following:

Element 'DOB' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'xsi:nil' was found.

Which JDK is correct? How to change the xml/xsd to be valid in both?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酷遇一生 2024-08-10 16:36:56

尝试将 attributeFormDefault="qualified" 放入 XSD 中。这应该没有什么区别,但这是一个快速测试。

另外:您没有将 DocumentBuilder 设置为名称空间感知。这肯定会破坏验证,但低于 1.5 和 1.6 也会破坏。

作为一般评论,解析时的验证更有用,因为您可以看到验证失败的内容的行号。下面是执行此操作的代码(schema 是之前创建的):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setSchema(schema);
DocumentBuilder db = dbf.newDocumentBuilder();

Try putting attributeFormDefault="qualified" in your XSD. That shouldn't make a difference, but it's a quick test.

Also: you don't set your DocumentBuilder to be namespace-aware. That would certainly break the validation, but it would break under 1.5 as well as 1.6.

And as a general comment, validation at the time of parsing is more useful, as you can see the line numbers of the content that failed validation. Here's the code to do it (schema is created previously):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(false);
dbf.setSchema(schema);
DocumentBuilder db = dbf.newDocumentBuilder();
去了角落 2024-08-10 16:36:56

我想说这是 Java 6 中的一个错误。您始终可以将 xsi 属性放入任何元素中。

它与这个错误非常相似,

https://bugs.java.com/bugdatabase/view_bug ?bug_id=6790700

尝试修复 6u14。它很可能也会解决你的问题。

I would say this is a bug in Java 6. You can always put xsi attributes in any element.

It's very similar to this bug,

https://bugs.java.com/bugdatabase/view_bug?bug_id=6790700

Try the fix 6u14. It most likely will fix yours too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文