开发者

Xerces on Android

I found several references in the mailinglist archive about Xerces, but it is still not clear to me if it is possible use Xerces succesfully in Android. Could you please provide me this information?

If the answer is Yes, could you please give me some tips or refe开发者_StackOverflowrences on how use Xerces instead of default Android XML parser?

Thanks in advance for your support

kind regards Barbara


Xerces extends the core library javax which leads to this problem in Android (mentioned by @Avi Cherry).

You can overcome this problem by repackaging the needed classes with a tool like JarJar. This has been done in the Xerces-for-Android, wherein the package mf is placed above the "normal" Xerces packages.


You can check out Androjena; it's a porting of Jena to the Android platform, and it uses Android's built-in XML parsers instead of Xerces. Hope this helps, bye!


While you -can- include Xerces in your project, you need to add the --core-library command-line option to the dex tool. But you shouldn't do this, because when the javax/xml/parsers/DocumentBuilder.class class (for example) IS finally supported by an SDK version, your application will likely break. Instead, you should probably use the jarjar utility to re-package xerces into a self-contained library with unique package names.

Note that the error message that 'dex' gives you if you include a java or javax package WITHOUT the --core-library option, involves the phrase:

the path you are on will ultimately lead to pain, suffering, grief, and lamentation.

The same error message also suggests that you use JarJar to repackage the library.


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.
 */
public class XmlUtil {

    /**
     * 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. 
     */
    public static boolean validate(String xmlFilePath, String xmlSchemaFilePath) {

        // parse an XML document into a DOM tree
        DocumentBuilder parser = 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(new File(xmlFilePath));

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

            // load a WXS schema, represented by a Schema instance
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Schema schema = factory.newSchema(schemaFile);

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

        return true;
    }
}

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.
 */public class XmlUtil {

    /**
     * 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. 
     */
    public static boolean validate(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 {
            SchemaFactory  factory = new XMLSchemaFactory();
            Source schemaFile = new StreamSource(new File(xmlSchemaFilePath));
            Source xmlSource = new StreamSource(new File(xmlFilePath));
            Schema schema = factory.newSchema(schemaFile);
            Validator validator = schema.newValidator();
            validator.validate(xmlSource);
        } catch (SAXException e) {
            return false;
        } catch (IOException e) {
            return false;
        } catch (Exception e) {
            // Catches everything beyond: SAXException, and IOException.
            e.printStackTrace();
            return false;
        } catch (Error e) {
            // Needed this for debugging when I was having issues with my 1st set of code.
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

Some Side Notes:

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

public static void createFileFromString(String fileText, String fileName) {
    try {
        File file = new File(fileName);
        BufferedWriter output = new BufferedWriter(new FileWriter(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:

String path = 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.


You can use Xerces on Android. Simply place the Xerces jar into your lib directory and add it to our Android path. When the project gets built it will translate the Xerces byte code into Android/Dalvik bytecode and bundle it into your APK. I've used it successfully on my project.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜