• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

How to get the location of invalid data during schema validation in Java

 
Maheee Mahaaa
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am validating xml using validator :

Validator validator = schema.newValidator();
validator.validate(xmlSoruce);

I can get line number, column number and error message. What I want is I want to get the location(xpath) of the invalid data. I am trying to use altova API since altova validator can display the location of invalid data. I need help to get the path of the invalid data(xpath).
 
g tsuji
Ranch Hand
Posts: 666
3
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have not mentioned what kind of parser that is an important element as I can imagine different parser requires different treatment. Also you have not mentioned what kind of schema to validate. An xsd schema shouldn't be a take-it-for-granted, though one would probably guess it is, as validate can be against a DTD or relaxng or anything one can imagine.

If you use sax parser to validate, you have to build the xpath yourself from the element/attribute where the validation fails. (Actually dom parser as well in the same sense.) Jaxb2-commons project has a subproject called xpath_tracker. You can study it and it would definitely help. However, I am not ready to help starting from zero...
 
Maheee Mahaaa
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you very much Ranch,
here is a detailed view of the code I am doing. I am doing XSD schema validation and sax parser. In the error handler I have, I want to show the the detail message of the failed element since the client is generating xml from table structure and give me to validate. So the line number doesn't help them because once I show them the error message they are going back to the table to modify the invalid data. For eg, if school name is invalid, I will show the school Id, district(parent of school node), region(parent of district) .... So I am hoping that if I get the XPath of the failed element, I can get the values of all the elements above the failed node.
Thanks again:

Here is the sample code I have:



package stax;

import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.ValidatorHandler;
import javax.xml.XMLConstants;
import javax.xml.bind.Element;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;

import org.xml.sax.InputSource;
import javax.xml.validation.Validator;
import java.io.*;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ErrorHandler;

class XsdSchemaSaxValidatorWithErrorHandler {
private static int errorCount = 0;
private static Schema schema = loadSchema("src\\files\\InterchangeEducationOrganizationExension.xsd");
private static final StreamSource XML = new StreamSource("src\\files\\InterchangeEducationOrganizationExension.xml");
//XMLStreamReader reader = XMLInputFactory.newFactory().createXMLStreamReader(XML);

private static // creating a Validator instance
Validator validator = schema.newValidator();
public static void main(String[] args) {

validateXml(schema,
"src\\files\\InterchangeEducationOrganizationExension.xml");

}

public static void validateXml(Schema schema, String xmlName) {
try {
ValidatorHandler vh = schema.newValidatorHandler();

System.out.println();
System.out.println("Validator Class: "
+ validator.getClass().getName());

// setting my own error handler
validator.setErrorHandler(new MyErrorHandler());

// preparing the XML file as a SAX source
SAXSource source = new SAXSource(new InputSource(
new java.io.FileInputStream(xmlName)));

//source.getXMLReader().s
// validating the SAX source against the schema
validator.validate(source);
System.out.println();
if (errorCount > 0) {
System.out.println("Failed with errors: " + errorCount);
} else {
System.out.println("Passed.");
}

} catch (Exception e) {
// catching all validation exceptions
System.out.println();
System.out.println(e.toString());
}
}

public static Schema loadSchema(String name) {
Schema schema = null;
try {
String language = XMLConstants.W3C_XML_SCHEMA_NS_URI;
SchemaFactory factory = SchemaFactory.newInstance(language);
schema = factory.newSchema(new File(name));
} catch (Exception e) {
System.out.println(e.toString());
}
return schema;
}

static class MyErrorHandler implements ErrorHandler {

public void fatalError(SAXParseException e) throws SAXException {
System.out.println(e.toString());
System.out.println("Error occured at line number :: " + e.getLineNumber());
System.out.println("Error occured at column :: " + e.getColumnNumber());
System.out.println("Error occured SystemId :: " + e.getSystemId());

throw e;
}

public void error(SAXParseException e) throws SAXException {
System.out.println(e.toString());
System.out.println("Error occured at line number :: " + e.getLineNumber());
System.out.println("Error occured at column :: " + e.getColumnNumber());
errorCount++;
Object element = validator.getProperty("http://apache.org/xml/properties/input-buffer-size");
System.out.println(element.toString());
// continue with validatin process
// throw e;
}

public void warning(SAXParseException e) throws SAXException {
System.out.println(e.toString());
}
}
}
 
g tsuji
Ranch Hand
Posts: 666
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is the project page of xpath_tracker with crucial implementation detail.
http://java.net/projects/jaxb2-commons/lists/cvs/archive/2007-03/message/13

And this blog provide a bit of motivation that might resonate your desired output.
http://weblogs.java.net/blog/kohsuke/archive/2007/03/reporting_valid.html
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic