Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get error's line number while validating a XML file against a XML schema

Tags:

java

xml

xsd

sax

I'm trying to validade a XML against a W3C XML Schema.

The following code does the job and reports when error occurs. But I'm unable to get line number of the error. It always returns -1.

Is there a easy way to get the line number?

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.Document;
import org.xml.sax.SAXParseException;

    public class XMLValidation {

        public static void main(String[] args) {

            try {
                DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                Document document = parser.parse(new File("myxml.xml"));

                SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
                Source schemaFile = new StreamSource(new File("myschema.xsd"));

                Schema schema = factory.newSchema(schemaFile);

                Validator validator = schema.newValidator();

                validator.validate(new DOMSource(document));

            } catch (SAXParseException e) {
                System.out.println(e.getLineNumber());
                e.printStackTrace();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
like image 424
pablosaraiva Avatar asked Dec 03 '10 17:12

pablosaraiva


People also ask

How validation is done in XML explain with an example?

A complete XML file is considered to be valid XML document unless it has correct syntax and constraints defined in it. To check for the validation document type definitions follow two schemas and it is checked for well-doing so no need to consider the data and structure of the XML document.

How do you reference an XML schema?

Reference the XSD schema in the XML document using XML schema instance attributes such as either xsi:schemaLocation or xsi:noNamespaceSchemaLocation. Add the XSD schema file to a schema cache and then connect that cache to the DOM document or SAX reader, prior to loading or parsing the XML document.


2 Answers

I found this

http://www.herongyang.com/XML-Schema/Xerces2-XSD-Validation-with-XMLReader.html

that appears to provide the following details(to include line numbers)

Error:
   Public ID: null
   System ID: file:///D:/herong/dictionary_invalid_xsd.xml
   Line number: 7
   Column number: 22
   Message: cvc-datatype-valid.1.2.1: 'yes' is not a valid 'boolean' 
   value.

using this code:

/**
 * XMLReaderValidator.java
 * Copyright (c) 2002 by Dr. Herong Yang. All rights reserved.
 */
import java.io.IOException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
class XMLReaderValidator {
   public static void main(String[] args) {
      String parserClass = "org.apache.xerces.parsers.SAXParser";
      String validationFeature 
         = "http://xml.org/sax/features/validation";
      String schemaFeature 
         = "http://apache.org/xml/features/validation/schema";
      try {
         String x = args[0];
         XMLReader r = XMLReaderFactory.createXMLReader(parserClass);
         r.setFeature(validationFeature,true);
         r.setFeature(schemaFeature,true);
         r.setErrorHandler(new MyErrorHandler());
         r.parse(x);
      } catch (SAXException e) {
         System.out.println(e.toString()); 
      } catch (IOException e) {
         System.out.println(e.toString()); 
      }
   }
   private static class MyErrorHandler extends DefaultHandler {
      public void warning(SAXParseException e) throws SAXException {
         System.out.println("Warning: "); 
         printInfo(e);
      }
      public void error(SAXParseException e) throws SAXException {
         System.out.println("Error: "); 
         printInfo(e);
      }
      public void fatalError(SAXParseException e) throws SAXException {
         System.out.println("Fattal error: "); 
         printInfo(e);
      }
      private void printInfo(SAXParseException e) {
         System.out.println("   Public ID: "+e.getPublicId());
         System.out.println("   System ID: "+e.getSystemId());
         System.out.println("   Line number: "+e.getLineNumber());
         System.out.println("   Column number: "+e.getColumnNumber());
         System.out.println("   Message: "+e.getMessage());
      }
   }
}
like image 136
Mads Hansen Avatar answered Oct 11 '22 03:10

Mads Hansen


Replace this line:

validator.validate(new DOMSource(document));

by

validator.validate(new StreamSource(new File("myxml.xml")));

will let the SAXParseException contain line number & column number

like image 44
tiboo Avatar answered Oct 11 '22 03:10

tiboo