views:

1171

answers:

2

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"&gt;
  <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"&gt;
  <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?

+1  A: 

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();
kdgregory
thx. setNamespaceAware(true) solved my problem.
asalamon74
A: 

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,

http://bugs.sun.com/bugdatabase/view%5Fbug.do?bug%5Fid=6790700

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

ZZ Coder
I was using 1.6.0_14. Now I've upgraded to 1.6.0_16 but the result is the same.
asalamon74