Sunday, June 21, 2015

Validate XML With Referenced XSD File Using SAX Parser

Previously we learn how to validated a XML file with reference or internal schema using DOM parser. Here we do the same thing but using SAX parser.

Step 1:

  Create a  SAXParserFactory object.
      SAXParserFactory saxFactory = SAXParserFactory.newInstance();  

Step 2:
  Set SAXParserFactory object as NameSpaceAware true.
      saxFactory.setNamespaceAware(true);

Step 3:
  Set SAXParserFactory object as Validating true.
      saxFactory.setValidating(true);

Step 4:
   Set SAXParser Property.
      parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                    "http://www.w3.org/2001/XMLSchema");


Step 5:
  Set ErrorHandler to XMLReader object.
                xmlReader.setErrorHandler(
                    new ErrorHandler() {
                        @Override
                        public void warning(SAXParseException e) throws SAXException {
                            System.out.println("WARNING: " + e.getMessage()); // do nothing
                        }
                       
                        @Override
                        public void error(SAXParseException e) throws SAXException {
                            System.out.println("ERROR: " + e.getMessage());
                            throw e;
                        }
                       
                        @Override
                        public void fatalError(SAXParseException e) throws SAXException {
                            System.out.println("FATAL: " + e.getMessage());
                            throw e;
                        }
                    });


Step 6:
  Parse XML file .
    xmlReader.parse("file.xml");

Our complete code looks like that:

package SAXParser;

import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;


public class SAXParserValidation {

    public static void main(String[] args) {
        try {
            SAXParserFactory saxFactory = SAXParserFactory.newInstance();
            saxFactory.setValidating(true);
            saxFactory.setNamespaceAware(true);
            SAXParser parser = saxFactory.newSAXParser();
            parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                    "http://www.w3.org/2001/XMLSchema");
           
            XMLReader xmlReader = parser.getXMLReader();
            xmlReader.setErrorHandler(
                    new ErrorHandler() {
                        @Override
                        public void warning(SAXParseException e) throws SAXException {
                            System.out.println("WARNING: " + e.getMessage()); // do nothing
                        }
                       
                        @Override
                        public void error(SAXParseException e) throws SAXException {
                            System.out.println("ERROR: " + e.getMessage());
                            throw e;
                        }
                       
                        @Override
                        public void fatalError(SAXParseException e) throws SAXException {
                            System.out.println("FATAL: " + e.getMessage());
                            throw e;
                        }
                    });
            xmlReader.parse("file.xml");
        } catch (ParserConfigurationException | SAXException | IOException e) {
            System.out.println("!!!!!!!!!!!!!!!Error!!!!!!!!!!!!" + e.getMessage());
        }
    }
   


 XML File :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students  xsi:noNamespaceSchemaLocation="file.xsd"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <student id="1">
    <fname>TestFirstName</fname>
    <lname>TestLastName</lname>
    <sectionname rollno="1">A</sectionname>
  </student>
</students>




XML Schema :

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xs:element name="students" type="studentsType"/>
  <xs:complexType name="sectionnameType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:byte" name="rollno"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="studentType">
    <xs:sequence>
      <xs:element type="xs:string" name="fname"/>
      <xs:element type="xs:string" name="lname"/>
      <xs:element type="sectionnameType" name="sectionname"/>
    </xs:sequence>
    <xs:attribute type="xs:byte" name="id"/>
  </xs:complexType>
  <xs:complexType name="studentsType">
    <xs:sequence>
      <xs:element type="studentType" name="student"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Validate XML With Referenced XSD File Using DOM Parser

On the last post we learn how to validated a XML file against an external XML schema file. Now we try to learn how to validate a XML file against referenced or internal schema definition.

Step 1 :

Create DocumentBuilderFactory object as given below.
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); 

Step 2 :

Set DocumentBuilderFactory object as NameSpace Aware true.
     docFactory.setNamespaceAware(true);

Step 3:

Set DocumentBuilderFactory object as Validating true.
     docFactory.setValidating(true);

Until we set docFactory as NameSpaceAware it will not validate the XML file with referenced Schema if we only set the Validating as true.

Step 4:

Set Attribute on DocumentBuilderFactory.

 If schemalocation specified in the XML Document using the schemaLocation or  noNamespaceSchemaLocation attributes then use
    docFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
              "http://www.w3.org/2001/XMLSchema");


If schemalocation specified by the 'http://java.sun.com/xml/jaxp/properties/schemaSource' property then use
    docFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
              "http://www.w3.org/2001/XMLSchema");


    docFactory.setAttribute( "http://java.sun.com/xml/jaxp/properties/schemaSource", "file:test2.xsd");


Step 5:

Set ErrorHandler to DocumentBuilderFactory object. It is optional,  it is required if we try to catch different level of parsing error like warning, error, fatal error etc.

We can set this on DocumentBuilder Object like this.
      docBuilder.setErrorHandler(new DefaultErrorHandler());

Or if we want to implement our own then it looks like this.
            docBuilder.setErrorHandler(
                    new ErrorHandler() {
                        @Override
                        public void warning(SAXParseException e) throws SAXException {
                            System.out.println("WARNING: " + e.getMessage()); // do nothing
                        }

                        @Override
                        public void error(SAXParseException e) throws SAXException {
                            System.out.println("ERROR: " + e.getMessage());
                            throw e;
                        }

                        @Override
                        public void fatalError(SAXParseException e) throws SAXException {
                            System.out.println("FATAL: " + e.getMessage());
                            throw e;
                        }
                    });


Step 6 :

Now parse the XML file.
    docBuilder.parse(new File("file.xml"));

Our complete code looks like that:

package domparsing;

import com.sun.org.apache.xml.internal.utils.DefaultErrorHandler;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class DOMValidation {

    /**
     * @param args the command line arguments
     * @throws javax.xml.parsers.ParserConfigurationException
     * @throws org.xml.sax.SAXException
     * @throws java.io.IOException
     */
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            docFactory.setNamespaceAware(true);
            docFactory.setValidating(true);
            /**
             * This line is required if We setValidating as true
             * but no noNamespaceSchemaLocation defined in XML file.
             */

            //docFactory.setFeature("http://apache.org/xml/features/validation/dynamic", true);
            docFactory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
              "http://www.w3.org/2001/XMLSchema");
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            //docBuilder.setErrorHandler(new DefaultErrorHandler());

            docBuilder.setErrorHandler(
                    new ErrorHandler() {
                        @Override
                        public void warning(SAXParseException e) throws SAXException {
                            System.out.println("WARNING: " + e.getMessage()); // do nothing
                        }

                        @Override
                        public void error(SAXParseException e) throws SAXException {
                            System.out.println("ERROR: " + e.getMessage());
                            throw e;
                        }

                        @Override
                        public void fatalError(SAXParseException e) throws SAXException {
                            System.out.println("FATAL: " + e.getMessage());
                            throw e;
                        }
                    });
            /**
             * Commented line required if we want to
             * show the output after parsing it.One is
             * for using DOM and another is one using STAX.
             */

            //TransformerFactory.newInstance().newTransformer().transform(new StreamSource("file.xml"), new StreamResult(System.out));
            //TransformerFactory.newInstance().newTransformer().transform(new DOMSource(docBuilder.parse(new File("file.xml"))),new StreamResult(System.out));
            docBuilder.parse(new File("file.xml"));
        } catch (IOException | SAXException | ParserConfigurationException | IllegalArgumentException e) {
            System.out.println("!!!!!!!!!!!!!!!Error!!!!!!!!!!!!" + e.getMessage());
        }
    }
}


XML File :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students  xsi:noNamespaceSchemaLocation="file.xsd"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <student id="1">
    <fname>TestFirstName</fname>
    <lname>TestLastName</lname>
    <sectionname rollno="1">A</sectionname>
  </student>
</students>




XML Schema :

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xs:element name="students" type="studentsType"/>
  <xs:complexType name="sectionnameType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:byte" name="rollno"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="studentType">
    <xs:sequence>
      <xs:element type="xs:string" name="fname"/>
      <xs:element type="xs:string" name="lname"/>
      <xs:element type="sectionnameType" name="sectionname"/>
    </xs:sequence>
    <xs:attribute type="xs:byte" name="id"/>
  </xs:complexType>
  <xs:complexType name="studentsType">
    <xs:sequence>
      <xs:element type="studentType" name="student"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Saturday, June 13, 2015

XML Validation And WellFormedNess Checking In Java

Previously we learn how to read and write a XML with different parser. Now we will concentrate how to check the wellformedness and validity of a XML file.

Now question is what is wellformedness and what is the validation of a XML file.

  1. WellFormedNess  : It is related with XML syntax of an XML document for an example : XML document must have a single root element, the elements must be properly nested, tag names cannot begin with a number or contain certain characters, and so on.
  2. Valid : A valid XML document means that the document complies with the rules of a particular document specification.This can be done with DTD(Document Type Definition) or Schema. Before a document can be valid to a standard, it must start by being well-formed. An XML document cannot be valid until it is well-formed

WellFormedNess checked in java when parse() method called. So we don't need to do any extra thing for that.

Now we go to find the way how to validate the xml file.

There are two way because some time schema definition is defined into the XML file then we need to use internal XML Validation and some time we need to validate the XML file with external schema file when schema definition is not defined into the XML file.

Here we will try to learn how to validate a XML file against an external XML Schema file.

Step 1: 
    
     Set Schema Language
        String schemaLanguage=XMLConstants.W3C_XML_SCHEMA_NS_URI;
        

Step 2:

     Create SchemaFactory Object
        SchemaFactory schemaFactory=SchemaFactory.newInstance(schemaLanguage);
        

Step 3:

      Create Schema Object
          Schema schema=schemaFactory.newSchema(new File("XSD FilePath"));
       
      If we have multiple schema file then use Source Object array

         Schema schema=schemaFactory.newSchema(new StreamSource[]{new StreamSource(new File("XSD FilePath"))});


Step 4:


     Create Validator object
        Validator xmlValidator= schema.newValidator();

Step 5:


     Now call validate method and pass XML file as a parameter to validate. 
        xmlValidator.validate(new StreamSource(new File("XML FilePath")));

Complete Code Example :


import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.SAXException;

public class SchemaValidationExample {

    public static void main(String[] args) {
        try {
            /**
             * Define Schema Language.
             */

            String schemaLanguage = XMLConstants.W3C_XML_SCHEMA_NS_URI;
           
            /**
             * Create SchemaFactory Object.
             */

            SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);
           
            /**
             * Create Schema Object,here we pass Schema File
             * If we require multiple Schema File then use
             * StreamSource object array.
             */

            Schema schema = schemaFactory.newSchema(new File("file.xsd"));
           
            //To valide XML against multiple xchema file.
            //Schema schema=schemaFactory.newSchema(new StreamSource[]{new StreamSource(new File("file.xsd"))});
           
            /**
             * Create Validator Object.
             */
            Validator xmlValidator = schema.newValidator();

           
            /**
             * Validate XML File.
             */

            xmlValidator.validate(new StreamSource(new File("file.xml")));
           
        } catch (SAXException |IOException ex) {
            Logger.getLogger(SchemaValidationExample.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
 

 
XSD File :
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
  <xs:element name="students" type="studentsType"/>
  <xs:complexType name="sectionnameType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:byte" name="rollno"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="studentType">
    <xs:sequence>
      <xs:element type="xs:string" name="fname"/>
      <xs:element type="xs:string" name="lname"/>
      <xs:element type="sectionnameType" name="sectionname"/>
    </xs:sequence>
    <xs:attribute type="xs:byte" name="id"/>
  </xs:complexType>
  <xs:complexType name="studentsType">
    <xs:sequence>
      <xs:element type="studentType" name="student"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
        

XML File :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<students xsi:noNamespaceSchemaLocation="file.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <student id="1">
    <fname>TestFirstName</fname>
    <lname>TestLastName</lname>
    <sectionname rollno="1">A</sectionname>
  </student>
</students>

 
     

Saturday, June 6, 2015

Writing XML File With STAX Stream Parser

Here we try to learn how to use STAX Stream Parser in XML writing. We know that STAX stream parser is consuming lower memory and more efficient than STAX Event Parser . Now we follow this steps to create a XML file using STAX Stream Parser.

Step : 1
       Create XMLOutputFactory object.
          XMLOutputFactory xof = XMLOutputFactory.newFactory();

Step : 2 
        Create XMLStreamWriter object.

           XMLStreamWriter writer = xof.createXMLStreamWriter(new FileWriter("C:\\file.xml"));

 Step : 3
         Start Document
            writer.writeStartDocument();

         Start Element
           writer.writeStartElement("students");

         Add Attribute
            writer.writeAttribute("id", "1");

         Add Character in XML Node
            writer.writeCharacters("TestLaststName");

        End Element
             writer.writeEndElement();

        End Document
             writer.writeEndDocument();

Step : 4
      Flush XMLStreamWriter object and close this object.
        
          writer.flush();
          writer.close();


Complete Code Is Given Below :


package STAXParser;

import com.sun.xml.internal.txw2.output.IndentingXMLStreamWriter;
import java.io.FileWriter;
import java.io.IOException;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamResult;

public class STAXStreamWriter {

    public static void main(String[] args) throws IOException, XMLStreamException, TransformerConfigurationException, TransformerException {
        /**
         * Create XMLOutputFactory Object.
         */

        XMLOutputFactory xof = XMLOutputFactory.newFactory();

        /**
         * Create XMLStreamWriter Object.
         */

        XMLStreamWriter writer = xof.createXMLStreamWriter(new FileWriter("C:\\file.xml"));
//        XMLStreamWriter writer = xof.createXMLStreamWriter(new StreamResult(System.out));
        /**
         * This is created for formatting.
         */

        writer = new IndentingXMLStreamWriter(writer);

        /**
         * Handling Start Document,Start Element,Add Attribute,
         * Add Character,EndDocument and EndElement.
         */

        writer.writeStartDocument();
       
        writer.writeStartElement("students");
       
        writer.writeStartElement("student");
        writer.writeAttribute("id", "1");

        writer.writeStartElement("fname");
        writer.writeCharacters("TestFirstName");
        writer.writeEndElement();

        writer.writeStartElement("lname");
        writer.writeCharacters("TestLaststName");
        writer.writeEndElement();

        writer.writeStartElement("section");
        writer.writeAttribute("rollno", "1");
        writer.writeCharacters("A");
        writer.writeEndElement();
       
        writer.writeEndElement();
        writer.writeEndElement();
        writer.writeEndDocument();

        /**
         * Flush XMLStreamWriter Object and Close.
         */

        writer.flush();
        writer.close();
    }
}


OutPut :
 

<?xml version="1.0" encoding="UTF-8"?>
<studens>
    <student id="1">
        <fname>TestFirstName</fname>
        <lname>TestLastName</lname>
        <section rollno="1">A</section>
    </student>
</studens>

Writing XML File Using STAX Event Parser

Using STAX parser is another way to write XML file. As we know STAX have two type of parsing technique one is Event or Iterator and another one is Stream or Cursor type,here STAX have same two types to write XML file.

Here we take a look on STAX event Parser, later we will know the another one.

Step 1 : 
      Create XMLOutputFactory object.
        XMLOutputFactory outFactory=XMLOutputFactory.newFactory();


Step 2 :
      Create XMLEventWriter object.
         XMLEventWriter xew=outFactory.createXMLEventWriter(new FileWriter("File Name"));

Step 3:
      Create XMLEventFactoryobject.
         XMLEventFactory evntFactory=XMLEventFactory.newFactory();

Step 4 :
      Start Document
         xew.add(evntFactory.createStartDocument());
     
      StartElement
        xew.add(evntFactory.createStartElement("", "", "Element Name"));   

      Add Attribute
        xew.add(evntFactory.createAttribute("Attribute Name", "Attribute Value"));

      Add Character
        xew.add(evntFactory.createCharacters("XML Node Character Value"));
 
     Close Element
        xew.add(evntFactory.createEndElement("", "", "Element Name Which we want to close"));
     
     Close Document 
        xew.add(evntFactory.createEndDocument());

Step 5 :
     Flush the writer object.
        xew.flush();

Step 6 :
     Close writer object.
        xew.close();
       

Complete Code Given Below :

package STAXParser;

import java.io.FileWriter;
import java.io.IOException;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;

public class STAXEventWriter {

    public static void main(String[] args) throws IOException, XMLStreamException {
        

        /**
         * Create XMLOutputFactory object.
         */

 
        XMLOutputFactory outFactory=XMLOutputFactory.newFactory();
        

        /**
         * Create XMLEventWriter object.
         */

 
        XMLEventWriter xew=outFactory.createXMLEventWriter(new FileWriter("C:\\file.xml"));
        //XMLEventWriter xew=outFactory.createXMLEventWriter(System.out);


        /**
         * Create XMLEventFactory object.
         */

        XMLEventFactory evntFactory=XMLEventFactory.newFactory();
       
        /**
         * This are created to decorate XML file.
         */

 
        XMLEvent end = evntFactory.createDTD("\n");
        XMLEvent tab = evntFactory.createDTD("\t");
       
        /**
         * Handling Stat Document, CreateElement, Add Attribute
         * Create Characters, Close Element and close Document.
         */

        xew.add(evntFactory.createStartDocument());
        xew.add(end);
       
        xew.add(evntFactory.createStartElement("", "", "studens"));
        xew.add(end);
        xew.add(tab);
       
        xew.add(evntFactory.createStartElement("", "", "student"));
        xew.add(evntFactory.createAttribute("id", "1"));
        xew.add(end);
        xew.add(tab);
        xew.add(tab);
       
        xew.add(evntFactory.createStartElement("", "", "fname"));
        xew.add(evntFactory.createCharacters("TestFirstName"));
        xew.add(evntFactory.createEndElement("", "", "fname"));
        xew.add(end);
        xew.add(tab);
        xew.add(tab);
       
        xew.add(evntFactory.createStartElement("", "", "lname"));
        xew.add(evntFactory.createCharacters("TestLastName"));
        xew.add(evntFactory.createEndElement("", "", "lname"));
        xew.add(end);
        xew.add(tab);
        xew.add(tab);
       
        xew.add(evntFactory.createStartElement("", "", "section"));
        xew.add(evntFactory.createAttribute("rollno", "1"));
        xew.add(evntFactory.createCharacters("A"));
        xew.add(evntFactory.createEndElement("", "", "section"));
        xew.add(end);
        xew.add(tab);
       
        xew.add(evntFactory.createEndElement("", "", "student"));
        xew.add(end);
       
        xew.add(evntFactory.createEndElement("", "", "students"));
        xew.add(evntFactory.createEndDocument());
       
        /**
         * Flush writer object and Close this object.
         */

        xew.flush();
        xew.close();
    }
}


OutPut :
 

<?xml version="1.0" encoding="UTF-8"?>
<studens>
    <student id="1">
        <fname>TestFirstName</fname>
        <lname>TestLastName</lname>
        <section rollno="1">A</section>
    </student>
</studens>