[jdom-interest] JDOM in memory schema validation

Laurent Bihanic laurent.bihanic at atosorigin.com
Mon Mar 24 09:30:44 PST 2003


Hi,

Gernot Koller wrote:
> I've seen you are planning to implement in memory schema validation for
> JDOM which would be a quite cool feature.

Although it is just quick-and-dirty code, the attached SchemaVerifier works 
fine as long as your XML document uses a single schema.
It does strickly not perform in memory validation on a JDOM tree but uses 
SAXOutputter to feed a JDOM document into Sun's Multi Schema Validator.

To use it, you need the isorelax.jar and msv.jar from Sun's Multi Schema 
Validator (http://wwws.sun.com/software/xml/developers/multischema/).

Laurent
-------------- next part --------------

package org.jdom.contrib.schema;


import java.lang.ref.SoftReference;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.HashMap;

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

import org.iso_relax.verifier.Schema;
import org.iso_relax.verifier.Verifier;
import org.iso_relax.verifier.VerifierFactory;
import org.iso_relax.verifier.VerifierConfigurationException;

import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.output.SAXOutputter;


public class SchemaVerifier {

   private final static String DEFAULT_SCHEMA_TYPE =
                                        "http://www.w3.org/2001/XMLSchema";

   private final Map schemaCache = new HashMap();

   public Object getSchema(String uri, String type) throws JDOMException {
      try {
         if ((type == null) || (type.length() == 0)) {
            type = DEFAULT_SCHEMA_TYPE;
         }
         Map typedCache = (Map)(schemaCache.get(type));
         if (typedCache == null) {
            typedCache = new HashMap();
            schemaCache.put(type, typedCache);
         }

         Schema compiledSchema = null;
         SoftReference ref = (SoftReference)(typedCache.get(uri));
         if (ref != null) {
            compiledSchema = (Schema)(ref.get());
         }
         if (compiledSchema == null) {
            compiledSchema = VerifierFactory.newInstance(type).
                                                        compileSchema(uri);
            typedCache.put(uri, new SoftReference(compiledSchema));
         }
         return compiledSchema;
      }
      catch (Exception e) {
         throw new JDOMException(
            "Failed to parse schema \"" + uri + "\": " + e.getMessage(), e);
      }
   }

   public List verify(Document doc, String schemaUri) throws JDOMException
   {
      return verify(doc, schemaUri, null);
   }

   public List verify(Document doc, String schemaUri, String schemaType)
                                                        throws JDOMException
   {
      if ((schemaType == null) || (schemaType.length() == 0)) {
         schemaType = DEFAULT_SCHEMA_TYPE;
      }
      return verify(doc, getSchema(schemaUri, schemaType));
   }

   public List verify(Document doc, Object schema) throws JDOMException
   {
      if (schema instanceof Schema == false) {
         throw new IllegalArgumentException("schema");
      }

      ValidationErrorHandler errorHandler = new ValidationErrorHandler();

      try {
         Verifier verifier = ((Schema)schema).newVerifier();
         verifier.setErrorHandler(errorHandler);

         new SAXOutputter(verifier.getVerifierHandler()).output(doc);
      }
      catch (VerifierConfigurationException e) {
         throw new JDOMException(
            "Failed to allocate schema vierifier: " + e.getMessage(), e);
      }
      catch (SAXException e) { /* Ignore... */ }

      // Retrieve validation errors
      return errorHandler.getErrors();
   }

   private static class ValidationErrorHandler implements ErrorHandler
   {
      private List errors = new LinkedList();

      public List getErrors() {
         return (errors.size() == 0)? null: this.errors;
      }

      public void fatalError(SAXParseException e) throws SAXException {
         error(e);
         throw e;
      }
      public void error(SAXParseException e) throws SAXException {
         this.errors.add(e);
      }
      public void warning(SAXParseException e) throws SAXException {
         error(e);
      }
   }
}

-------------- next part --------------

import java.util.List;
import java.util.Iterator;

import org.jdom.Document;
import org.jdom.input.SAXBuilder;

import org.jdom.contrib.schema.SchemaVerifier;

public class TestSchemaVerifier
{
   public static void main(String[] args) throws Exception
   {
      if (args.length < 2) {
         System.out.println("TestMemoryValidation file schema");
         System.exit(2);
      }

      SchemaVerifier verifier = new SchemaVerifier();

      List errors = verifier.verify(new SAXBuilder().build(args[0]), args[1]);
      if (errors != null) {
         for (Iterator i=errors.iterator(); i.hasNext(); ) {
            System.out.println(i.next());
         }
      }
      else {
         System.out.println(
                args[0] + " complies with W3C XML schema \"" + args[1] + "\"");
      }
   }
}



More information about the jdom-interest mailing list