代码之家  ›  专栏  ›  技术社区  ›  asalamon74

JAVA XML验证JDK 1.5 JDK 1.6差异

  •  1
  • asalamon74  · 技术社区  · 16 年前

    我对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;
    }
    

    测试程序在JDK1.5和JDK1.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更改为在两者中都有效?

    2 回复  |  直到 16 年前
        1
  •  1
  •   kdgregory    16 年前

    尝试将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();
    
        2
  •  0
  •   ZZ Coder    16 年前

    我认为这是Java 6中的一个bug。您总是可以在任何元素中放置XSI属性。

    它和这个bug非常相似,

    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6790700

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