Skip to content Skip to sidebar Skip to footer

Validate Xml Against Schema On Android Using Xerces

So, after consulting with this thread that the javax.xml.validation library does not work on Android I had to find another solution. I have tried using the Xerces API and although

Solution 1:

The problem is that android doesn't have xerces and validating interface =) And BTW xerces ASIS from box don't work in android, because some classes are excluded from final APK because they compiled with different target. But you can simply add validating from xerce:

You can use xerces and native schema validation (in java) in adnroid - you have to download xerces sources and (after some simple manipulations) include it to your own code - you will be able to use DocumentBuilderFactory.setShema method.

https://stackoverflow.com/questions/13142567/xml-schema-validation-xmlsignature-with-xerces-in-android

Solution 2:

It's a knowed issue posted by google at http://code.google.com/p/android/issues/detail?id=7395

The solution is use Apache Xerces ported to Android like you say. There is a proyect here http://code.google.com/p/xerces-for-android/

You have to do a svn chekout and export the proyect to a jar file to use as a library in your android proyect.

The code to instance SchemaFactory change a little. I show you an example:

import mf.javax.xml.validation.Schema;
import mf.javax.xml.validation.SchemaFactory;
import mf.javax.xml.validation.Validator;
import mf.org.apache.xerces.jaxp.validation.XMLSchemaFactory;


SchemaFactoryfactory=newXMLSchemaFactory();
Schemaesquema= factory.newSchema(".../file.xsd");

Solution 3:

I found I was not able to get the regular xerces to work with Android, however I did find Xerces-for-Android, which I got working. The following are details of the setup and some example code. Good luck :)

The following worked for me:

  1. Create a validation utility.
  2. Get both the xml and xsd into file on the android OS and use the validation utility against it.
  3. Use Xerces-For-Android to do the validation.

Android does support some packages which we can use, I created my xml validation utility based on: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

My initial sandbox testing was pretty smooth with java, then I tried to port it over to Dalvik and found that my code did not work. Some things just aren't supported the same with Dalvik, so I made some modifications.

I found a reference to xerces for android, so I modified my sandbox test of (the following doesn't work with android, the example after this does):

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;

/**
 * A Utility to help with xml communication validation.
 */publicclassXmlUtil {

    /**
     * Validation method. 
     * Base code/example from: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse. 
     */publicstaticbooleanvalidate(String xmlFilePath, String xmlSchemaFilePath) {

        // parse an XML document into a DOM treeDocumentBuilderparser=null;
        Document document;

        // Try the validation, we assume that if there are any issues with the validation// process that the input is invalid.try {
            // validate the DOM tree
            parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            document = parser.parse(newFile(xmlFilePath));

            // create a SchemaFactory capable of understanding WXS schemasSchemaFactoryfactory= SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            // load a WXS schema, represented by a Schema instanceSourceschemaFile=newStreamSource(newFile(xmlSchemaFilePath));
            Schemaschema= factory.newSchema(schemaFile);

            // create a Validator instance, which can be used to validate an instance documentValidatorvalidator= schema.newValidator();
            validator.validate(newDOMSource(document));
        } catch (Exception e) {
            // Catches: SAXException, ParserConfigurationException, and IOException.returnfalse;
        }     

        returntrue;
    }
}

The above code had to be modified some to work with xerces for android (http://gc.codehum.com/p/xerces-for-android/). You need SVN to get the project, the following are some crib notes:

download xerces-for-android
    download silk svn (for windows users) from http://www.sliksvn.com/en/download
        install silk svn (I did complete install)
        Once the install is complete, you should have svn in your system path.
        Test by typing "svn" from the command line.
        I went to my desktop then downloaded the xerces project by:
            svn checkout http://xerces-for-android.googlecode.com/svn/trunk/ xerces-for-android-read-only
        You should then have a new folder on your desktop called xerces-for-android-read-only

With the above jar (Eventually I'll make it into a jar, just copied it directly into my source for quick testing. If you wish to do the same, you can making the jar quickly with Ant (http://ant.apache.org/manual/using.html)), I was able to get the following to work for my xml validation:

import java.io.File;
import java.io.IOException;

import mf.javax.xml.transform.Source;
import mf.javax.xml.transform.stream.StreamSource;
import mf.javax.xml.validation.Schema;
import mf.javax.xml.validation.SchemaFactory;
import mf.javax.xml.validation.Validator;
import mf.org.apache.xerces.jaxp.validation.XMLSchemaFactory;

import org.xml.sax.SAXException;

/**
 * A Utility to help with xml communication validation.
 */publicclassXmlUtil {

    /**
     * Validation method. 
     * 
     * @param xmlFilePath The xml file we are trying to validate.
     * @param xmlSchemaFilePath The schema file we are using for the validation. This method assumes the schema file is valid.
     * @return True if valid, false if not valid or bad parse or exception/error during parse. 
     */publicstaticbooleanvalidate(String xmlFilePath, String xmlSchemaFilePath) {

        // Try the validation, we assume that if there are any issues with the validation// process that the input is invalid.try {
            SchemaFactoryfactory=newXMLSchemaFactory();
            SourceschemaFile=newStreamSource(newFile(xmlSchemaFilePath));
            SourcexmlSource=newStreamSource(newFile(xmlFilePath));
            Schemaschema= factory.newSchema(schemaFile);
            Validatorvalidator= schema.newValidator();
            validator.validate(xmlSource);
        } catch (SAXException e) {
            returnfalse;
        } catch (IOException e) {
            returnfalse;
        } catch (Exception e) {
            // Catches everything beyond: SAXException, and IOException.
            e.printStackTrace();
            returnfalse;
        } catch (Error e) {
            // Needed this for debugging when I was having issues with my 1st set of code.
            e.printStackTrace();
            returnfalse;
        }

        returntrue;
    }
}

Some Side Notes:

For creating the files, I made a simple file utility to write string to files:

publicstaticvoidcreateFileFromString(String fileText, String fileName) {
    try {
        File file = newFile(fileName);
        BufferedWriter output = newBufferedWriter(newFileWriter(file));
        output.write(fileText);
        output.close();
    } catch ( IOException e ) {
       e.printStackTrace();
    }
}

I also needed to write to an area that I had access to, so I made use of:

Stringpath=this.getActivity().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;   

A little hackish, it works. I'm sure there is a more succinct way of doing this, however I figured I'd share my success, as there weren't any good examples that I found.

Post a Comment for "Validate Xml Against Schema On Android Using Xerces"