2010-06-28 5 views
31

Mit dem Android SDK, der folgende Code in einer Ebene leer Aktivität versagt:SchemaFactory unterstützt W3C-XML-Schema in Plattform-Ebene 8 nicht?

@Override 
protected void onStart() { 
    super.onStart(); 

    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
} 

Der 2,2-Emulator logcat zeigt diese Ausnahme:

06-28 05:38:06.107: WARN/dalvikvm(495): threadid=1: thread exiting with uncaught exception (group=0x4001d800) 
06-28 05:38:06.128: ERROR/AndroidRuntime(495): FATAL EXCEPTION: main 
     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.HelloWorldActivity}: java.lang.IllegalArgumentException: http://www.w3.org/2001/XMLSchema 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
     at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
     at android.os.Handler.dispatchMessage(Handler.java:99) 
     at android.os.Looper.loop(Looper.java:123) 
     at android.app.ActivityThread.main(ActivityThread.java:4627) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:521) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
     at dalvik.system.NativeStart.main(Native Method) 
     Caused by: java.lang.IllegalArgumentException: http://www.w3.org/2001/XMLSchema 
     at javax.xml.validation.SchemaFactory.newInstance(SchemaFactory.java:194) 
     at com.example.HelloWorldActivity.onStart(HelloWorldActivity.java:26) 
     at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129) 
     at android.app.Activity.performStart(Activity.java:3781) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2636) 
     ... 11 more 

Die Javadoc of SchemaFactory „Platform Standard SchemaFactory erwähnt in einer ruhigen Implementierung spezifische Art. Es muss eine Plattform Standard-SchemaFactory für W3C XML-Schema sein. "

+0

Ich habe das gleiche Problem mit Plattform-Ebenen 9 und 10. Wie von [diese Antwort] (http://stackoverflow.com/questions/801632/android-schema/802150#802150) angegeben, scheint es, dass es derzeit keine gibt XML-Schema-Unterstützung in Android. –

+0

[sieht auch ähnlich] (http://stackoverflow.com/questions/2694259/android-adt-eclipse-plugin-parsesdkcontent-failed) aber die Antwort hat nicht geholfen –

Antwort

1

Sie könnten einige Glück Umverpackung xerces mit Jarjar haben und vorbei dann

"org.apache.xerces.jaxp.validation.XMLSchemaFactory" 

zu

SchemaFactory.newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) 

wenn Sie API verwenden> = 9 oder direkt instanziieren

org.apache.xerces.jaxp.validation.XMLSchemaFactory 

Wenn Sie API 8 verwenden. Es funktioniert möglicherweise überhaupt nicht mit einer älteren API als diese.

2

Ich hatte das gleiche Problem und las viele Beiträge, bevor ich eine Antwort bekam, die für mich funktionierte. Der Bezug auf die Konstante wird bei Dalvik nicht funktionieren. Ich musste feststellen, dass ich meinen Code ändern musste, um mit dem Xerces-für-Android-Projekt arbeiten zu können, und dann konnte ich die XML-Validierung erhalten, die ich wollte. Was wahrscheinlich am meisten mit der Variablenreferenz passiert. Im Folgenden finden Sie Details zum Setup und einen Beispielcode, der zeigt, wie die Validierung für Android funktioniert.

Die folgenden für mich gearbeitet:

  1. ein Validierungs-Dienstprogramm erstellen.
  2. Holen Sie sich die Xml und Xsd in Datei auf dem Android-Betriebssystem und verwenden Sie das Validierungsprogramm dagegen.
  3. Verwenden Sie Xerces-For-Android, um die Validierung durchzuführen.

Android hat einige Pakete unterstützen, die wir verwenden können, ich mein XML-Validierung Dienstprogramm erstellt auf Basis von: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

Mein ersten Sandbox-Test mit Java ziemlich glatt war, dann habe ich versucht, es in dem Hafen Dalvik über und festgestellt, dass mein Code nicht funktioniert hat. Einige Dinge werden bei Dalvik nicht gleich unterstützt, daher habe ich einige Änderungen vorgenommen.

ich einen Hinweis auf xerces für Android gefunden, so modifizierte ich mein Sandbox Test (folgendes mit Android nicht funktioniert, das Beispiel danach tut):

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; 
    } 
} 

Der obige Code hatte geändert werden, um mit Xerces für Android zu arbeiten (http://gc.codehum.com/p/xerces-for-android/). Sie müssen SVN das Projekt zu erhalten, die folgenden sind einige Krippe Hinweise:

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 

Mit dem obigen Glas (Schließlich werde ich es in ein Glas machen, es nur für einen schnellen Test direkt in meine Quelle kopiert.Wenn Sie das gleiche tun möchten, können Sie das Glas schnell mit Ant machen (http://ant.apache.org/manual/using.html)), konnte ich folgendes arbeiten für meine XML-Validierung erhalten:

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; 
    } 
} 

Einige Randnotizen:

für die Dateien erstellen, habe ich eine einfache Datei-Dienstprogramm Zeichenfolge Dateien zu schreiben:

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(); 
    } 
} 

ich auch in einen Bereich zu schreiben, benötigt, die ich Zugang zu hatte, so machte ich Gebrauch von:

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

Ein wenig hackish, es funktioniert. Ich bin mir sicher, dass es eine prägnantere Vorgehensweise gibt, aber ich dachte, dass ich meinen Erfolg teilen würde, da es keine guten Beispiele gab, die ich fand.

+0

Großartig schreiben, ich schätze den Detaillierungsgrad in Dies – GMLewisII