<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MetaBinary &#187; xml</title>
	<atom:link href="http://metabinary.com/tag/xml/feed/" rel="self" type="application/rss+xml" />
	<link>http://metabinary.com</link>
	<description>Beyond 0 and 1.</description>
	<lastBuildDate>Mon, 21 Dec 2009 22:26:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Validating XML against an XSD in Java</title>
		<link>http://metabinary.com/2009/06/validating-xml-against-an-xsd-in-java/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=validating-xml-against-an-xsd-in-java</link>
		<comments>http://metabinary.com/2009/06/validating-xml-against-an-xsd-in-java/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 03:06:30 +0000</pubDate>
		<dc:creator>redwildfire13</dc:creator>
				<category><![CDATA[Joe's Stories]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[validate]]></category>
		<category><![CDATA[xml]]></category>
		<category><![CDATA[xsd]]></category>

		<guid isPermaLink="false">http://metabinary.com/?p=54</guid>
		<description><![CDATA[I&#8217;ve been working on a REST interface for adding, removing, and viewing Hazard information in the database at work (I&#8217;m at the Pacific Disaster Center). Setting up REST was pretty easy, but validating the input has been a bit of a problem. Since it took me a while to find a good solution, I figured [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a REST interface for adding, removing, and viewing Hazard information in the database at work (I&#8217;m at the <a href="http://www.pdc.org">Pacific Disaster Center</a>). Setting up REST was pretty easy, but validating the input has been a bit of a problem. Since it took me a while to find a good solution, I figured I&#8217;d post how I went about taking care of my validation problems here.</p>
<p><span id="more-54"></span></p>
<p>First, I started out with the main resource part, which you can find the basic to anywhere:</p>
<pre><textarea rows="18" cols="70">
import java.io.InputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.apps.validator.Validate;

@POST
  @Path(&quot;get/validate_hazard&quot;)
  @Produces(&quot;text/html&quot;)
  @Consumes(&quot;application/xml&quot;)
  public String validateHazard( InputStream hazardXml )
  {
    return Validate.isValid(hazardXml);
  }
</textarea></pre>
<p>(Some code has been hacked down to necessary parts. Leave a comment if you need more complete code.)</p>
<p>I originally had this method accept a Bean that I then used for all my updating or adding. Having it put the data into an InputStream was what took me the longest to figure out, even though it seems so obvious to me now. I probably could have put it into an InputSource or SAXSource if I wanted, but I&#8217;m still experimenting. Either way, there are several ways to go about validating.</p>
<p>To start everything off, here is how the input XML looks:</p>
<pre><textarea rows="5" cols="70">
&lt;hazardbean&gt;
  ...
  &lt;create_date&gt;2009-06-04&lt;/create_date&gt;
  ...
&lt;/hazardbean&gt;
</textarea></pre>
<p>And here is how my XSD looks:</p>
<pre><textarea rows="13" cols="70">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;xs:schema xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;&gt;
 &lt;xs:element name=&quot;hazardBean&quot;&gt;
    &lt;xs:complexType&gt;
      &lt;xs:sequence&gt;
       ...
       &lt;xs:element name=&quot;create_Date&quot; type=&quot;xs:date&quot; maxOccurs=&quot;1&quot; /&gt;
       ...
      &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;
 &lt;/xs:element&gt;
&lt;/xs:schema&gt;
</textarea></pre>
<p>The first way I found is relatively simple. You can read the original article I modified it from called <a href="http://www.ibm.com/developerworks/library/x-javaxmlvalidapi.html">The Java XML Validation API</a> at IBM&#8217;s site. Here is my take on it:</p>
<pre><textarea rows="25" cols="70">
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.transform.Source;
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 static String validator(InputStream hazard)
{
  String result = &quot;Failed.&quot;;
    try
    {
    // 1. Lookup a factory for the W3C XML Schema language
      SchemaFactory factory = SchemaFactory.newInstance(&quot;http://www.w3.org/2001/XMLSchema&quot;);

    // 2. Compile the schema.
    // Here the schema is loaded from a java.io.File, but you could use
    // a java.net.URL or a javax.xml.transform.Source instead.
      File schemaLocation = new File(&quot;C:/xml/hazardBean.xsd&quot;);
    Schema schema = factory.newSchema(schemaLocation);

    // 3. Get a validator from the schema.
      Validator validator = schema.newValidator();

    // 4. Parse the document you want to check.
      Source source = new StreamSource(hazard);

    // 5. Check the document
        validator.validate(source);
        result = &quot;XML is valid.&quot;;
    }
    catch (SAXException ex)
    {
        result = &quot;XML is not valid because &quot; + ex.getMessage();
    }
    catch (Exception ex)
    {
      result = &quot;XML is not valid because &quot; + ex.getMessage();
    }
    return result;
}
</textarea></pre>
<p>Pretty much the same thing their article covers. This will spit me out a nice error when something is not valid that explains why. </p>
<p>The next way that I tried using DOM: </p>
<pre><textarea rows="25" cols="70">
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public static String validateXML(InputStream hazard)
  {
    String result = &quot;Failed.&quot;;
    try
    {
      // parse an XML document into a DOM tree
      DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
      parserFactory.setNamespaceAware(true);
      parserFactory.setValidating(true);
      // set attributes to handle XML namespace
      parserFactory.setAttribute(&quot;http://java.sun.com/xml/jaxp/properties/schemaLanguage&quot;, &quot;http://www.w3.org/2001/XMLSchema&quot;);
      parserFactory.setAttribute(&quot;http://java.sun.com/xml/jaxp/properties/schemaSource&quot;, &quot;http://localhost:8080/xml/hazardBean.xsd&quot;);

      DocumentBuilder parser = parserFactory.newDocumentBuilder();
      parser.setErrorHandler(new Handler());

      parser.parse( hazard );

      result = &quot;Success.&quot;;
      hazard.close();
    }
    catch (SAXException e)
    {
      m_logger.fatal( &quot;Parsing Error: &quot; + e.toString() );
    }
    catch (IOException e)
    {
      m_logger.fatal( &quot;IO Error: &quot; + e.toString() );
    }
    catch (Exception e)
    {
      m_logger.fatal( e.toString() );
    }
    return result;
  }
</textarea></pre>
<p>m_logger is just my companies logger class, a customized version of apache log4j.</p>
<p>IBM had another nice article on how to <a href="http://www.ibm.com/developerworks/library/x-tipeh.html">setup an ErrorHandler</a> that I found quite useful. It took me a minute to realize that you have to build your own. (Again, if you would like to see the one I built, just ask in the comments. They are pretty self explanatory though.)</p>
<p>This brings me to the very last one. Using SAX to parse:</p>
<pre><textarea rows="25" cols="70">
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

public static String validateXML(InputStream hazard)
  {
    String result = &quot;Failed.&quot;;
    try
    {
      // Prepare parser for validating
      SAXParserFactory parserFactory = SAXParserFactory.newInstance();
      parserFactory.setNamespaceAware(true);
      parserFactory.setValidating(true);
      parserFactory.setFeature(&quot;http://apache.org/xml/features/validation/schema&quot;, true);

      SAXParser parser = parserFactory.newSAXParser();

      // Set namespace properties
      parser.setProperty(&quot;http://java.sun.com/xml/jaxp/properties/schemaLanguage&quot;,
                         &quot;http://www.w3.org/2001/XMLSchema&quot;);
      parser.setProperty(&quot;http://java.sun.com/xml/jaxp/properties/schemaSource&quot;, &quot;http://localhost:8080/restdemo/docs/hazardBean.xsd&quot;);

      // Get reader to parse XML
      XMLReader xmlReader = parser.getXMLReader();
      xmlReader.setErrorHandler(new Handler());
      xmlReader.parse( new InputSource(hazard) );

      // Close input source
      hazard.close();
    }
    catch (SAXException e)
    {
      m_logger.fatal( &quot;Parsing Error: &quot; + e.toString() );
    }
    catch (IOException e)
    {
      m_logger.fatal( &quot;IO Error: &quot; + e.toString() );
    }
    catch (Exception e)
    {
      m_logger.fatal( e.toString() );
    }
    return result;
  }
</textarea></pre>
<p>That&#8217;s about all there is to it. This works perfectly for REST services to make sure that the user inputs good data and leaves you with less error checking in the end. I hope this has been helpful to anyone else out there looking for a way to validate their XML against an XSD using Java. </p>
]]></content:encoded>
			<wfw:commentRss>http://metabinary.com/2009/06/validating-xml-against-an-xsd-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

