How can I get more information about an invalid DOM element through Validator?

I am checking a DOM object in memory using a class javax.xml.validation.Validatoragainst an XSD schema. I get SAXParseExceptionthat throws during validation when there is some data corruption in the information from which I populate my DOM.

Error example:

org.xml.SAXParseException: cvc-datatype-valid.1.2.1: '??? "?? [???? G?>? P ~ tn ?? ~ 0? 1] 'is an invalid valud for' hexBinary '.

I hope there is a way to find the location of this error in my internal DOM memory and print the offending element and its parent element. My current code is:

public void writeDocumentToFile(Document document) throws XMLWriteException {
  try {
    // Validate the document against the schema
    Validator validator = getSchema(xmlSchema).newValidator();
    validator.validate(new DOMSource(document));

    // Serialisation logic here.

  } catch(SAXException e) {
    throw new XMLWriteException(e); // This is being thrown
  } // Some other exceptions caught here.
}

private Schema getSchema(URL schema) throws SAXException {
  SchemaFactory schemaFactory = 
    SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

  // Some logic here to specify a ResourceResolver

  return schemaFactory.newSchema(schema);
}

Validator#setErrorHandler(ErrorHandler handler), ErrorHandler SAXParseException, . DOM , -1 .

? , , DOM, , .

JDK 6 26 JDK 6 7 , .

EDIT: -

validator.setErrorHandler(new ErrorHandler() {
  @Override
  public void warning(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  @Override
  public void error(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  @Override
  public void fatalError(SAXParseException exception) throws SAXException {
    printException(exception);
    throw exception;
  }

  private void printException(SAXParseException exception) {
    System.out.println("exception.getPublicId() = " + exception.getPublicId());
    System.out.println("exception.getSystemId() = " + exception.getSystemId());
    System.out.println("exception.getColumnNumber() = " + exception.getColumnNumber());
    System.out.println("exception.getLineNumber() = " + exception.getLineNumber());
  }
});

:

exception.getPublicId() = null
exception.getSystemId() = null
exception.getColumnNumber() = -1
exception.getLineNumber() = -1
+4
2

Xerces ( Sun JDK), , , http://apache.org/xml/properties/dom/current-element- node :

...
catch (SAXParseException e)
{
    Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");

    System.out.println("Validation error: " + e.getMessage());
    System.out.println("Element: " + curElement);
}   

:

String xml = "<root xmlns=\"http://www.myschema.org\">\n" +
             "<text>This is text</text>\n" +
             "<number>32</number>\n" +
             "<number>abc</number>\n" +
             "</root>";

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
Schema schema = getSchema(getClass().getResource("myschema.xsd"));

Validator validator = schema.newValidator();
try
{
    validator.validate(new DOMSource(doc));
}
catch (SAXParseException e)
{
    Element curElement = (Element)validator.getProperty("http://apache.org/xml/properties/dom/current-element-node");

    System.out.println("Validation error: " + e.getMessage());
    System.out.println(curElement.getLocalName() + ": " + curElement.getTextContent());

    //Use curElement.getParentNode() or whatever you need here
}         

/ DOM, .

+5

SaxParseException SystemId PublicId. ?

0

All Articles