2010-06-28 5 views
31

Con l'SDK di Android, il codice seguente in una pianura di attività vuota fallisce:SchemaFactory non supporta lo schema XML W3C nel livello di piattaforma 8?

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

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

Il logcat 2.2 emulatore mostra questa eccezione:

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 

Il Javadoc of SchemaFactory menzioni "SchemaFactory predefinita piattaforma si trova in una implementazione specifica: deve esserci una piattaforma predefinita SchemaFactory per lo schema XML W3C. "

+0

Ho lo stesso problema con i livelli di piattaforma 9 e 10. Come indicato da [questa risposta] (http://stackoverflow.com/questions/801632/android-schema/802150#802150), sembra che al momento non ci sia Supporto dello schema XML in Android. –

+0

[Sembra anch'esso simile] (http://stackoverflow.com/questions/2694259/android-adt-eclipse-plugin-parsesdkcontent-failed) ma la risposta non ha aiutato –

risposta

1

si potrebbe avere qualche xerces fortuna ri-confezionamento con jarjar e poi passando

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

a

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

se si sta utilizzando API> = 9 o direttamente istanziare

org.apache.xerces.jaxp.validation.XMLSchemaFactory 

se si utilizza l'API 8. Potrebbe non funzionare affatto utilizzando un'API precedente.

2

Ho avuto lo stesso problema e ho letto molti post prima di ottenere una risposta che funzionasse per me. Il riferimento alla costante non funzionerà su Dalvik. Ho scoperto che dovevo modificare il mio codice per lavorare con il progetto Xerces-per-Android, quindi sono stato in grado di ottenere la convalida xml che cercavo. Che è più probabile ciò che stai facendo con la variabile reference. Di seguito sono riportati i dettagli della configurazione e alcuni esempi di codice che mostrano come far funzionare la convalida su Android.

Di seguito ha lavorato per me:

  1. Creare un programma di utilità di convalida.
  2. Ottieni sia il file xml che xsd nel file sul sistema operativo Android e utilizza l'utilità di convalida su di esso.
  3. Utilizzare Xerces-For-Android per eseguire la convalida.

Android supporta alcuni pacchetti che possiamo usare, ho creato il mio programma di utilità di convalida XML in base a: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html

mio test iniziale sandbox era abbastanza liscio con Java, quindi ho cercato di portarlo verso Dalvik e ho scoperto che il mio codice non funzionava. Alcune cose non sono supportate allo stesso modo con Dalvik, quindi ho apportato alcune modifiche.

ho trovato un riferimento a Xerces per Android, quindi ho modificato la mia prova sandbox del (seguente non funziona con Android, l'esempio dopo questo fa):

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

Il codice di cui sopra aveva da modificare alcuni per lavorare con xerces per Android (http://gc.codehum.com/p/xerces-for-android/). È necessario SVN per ottenere il progetto, i seguenti sono alcune note presepe:

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 

Con il vaso sopra (Alla fine ce la farò in un vaso, appena copiato direttamente nella mia fonte per il test rapido.Se si desidera fare lo stesso, si può fare rapidamente il vaso con Ant (http://ant.apache.org/manual/using.html)), sono stato in grado di ottenere quanto segue per lavorare per la mia convalida xml:

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

Alcune note collaterali:

per la creazione dei file, ho fatto un programma di utilità semplice file di scrivere stringhe di file:

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

ho anche bisogno di scrivere in una zona che ho avuto accesso a, così ho fatto uso di:

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

Un po 'di hacker, funziona. Sono sicuro che c'è un modo più succinto di farlo, tuttavia ho pensato che avrei condiviso il mio successo, in quanto non c'erano buoni esempi che ho trovato.

+0

Great write up, apprezzo il livello di dettaglio in Questo – GMLewisII

Problemi correlati