android - validar - validate xml against xsd
Excepción SchemaFactory.newInstance() (2)
Tuve el mismo problema y encontré muchas preguntas similares, pero no hay buenos ejemplos sobre cómo hacerlo. Lo siguiente es lo que hice con Xerces-for-Android para que mis cosas funcionen. Buena suerte :)
Lo siguiente funcionó para mí:
- Crea una utilidad de validación
- Obtenga tanto el xml como el xsd en el archivo en el sistema operativo Android y use la utilidad de validación en su contra.
- Use Xerces-For-Android para hacer la validación.
Android admite algunos paquetes que podemos usar, creé mi utilidad de validación xml en función de: http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/validation/package-summary.html
Mi prueba inicial de sandbox fue bastante suave con Java, luego traté de dárselo a Dalvik y descubrí que mi código no funcionaba. Algunas cosas simplemente no son compatibles con Dalvik, así que hice algunas modificaciones.
Encontré una referencia a xerces para Android, así que modifiqué mi prueba de sandbox ( lo siguiente no funciona con android, el ejemplo después de esto ):
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;
}
}
El código anterior tenía que modificarse para que funcione con xerces para Android ( http://gc.codehum.com/p/xerces-for-android/ ). Necesita SVN para obtener el proyecto, las siguientes son algunas notas de cuna:
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 el contenedor anterior (eventualmente lo convertiré en un contenedor, simplemente lo copié directamente en mi fuente para realizar pruebas rápidas. Si desea hacer lo mismo, puede hacer el contenedor rápidamente con Ant ( http: //ant.apache) .org / manual / using.html )), pude obtener lo siguiente para trabajar para mi validación 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;
}
}
Algunas notas secundarias:
Para crear los archivos, hice una sencilla utilidad de archivos para escribir cadenas en los archivos:
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();
}
}
También necesitaba escribir en un área a la que tenía acceso, así que hice uso de:
String path = this.getActivity().getPackageManager().getPackageInfo(getPackageName(), 0).applicationInfo.dataDir;
Un poco hackish, funciona. Estoy seguro de que hay una manera más sucinta de hacerlo, sin embargo, pensé que compartiría mi éxito, ya que no había ningún buen ejemplo que encontrara.
Estoy tratando de verificar un xml contra un esquema para Android, pero en la primera línea de la función, al crear la instancia de fábrica de esquema , recibo una excepción.
Línea de excepción:
schemaFactory = SchemaFactory.newInstance (XMLConstants.W3C_XML_SCHEMA_NS_URI);
También he usado XMLSchema-instance y XMLSchema , pero obtuve la misma excepción al principio.
He visto que muchas otras personas tienen el mismo problema, como este , pero todavía no he encontrado la respuesta a este problema.
FYI - Lo estoy usando en la siguiente función:
public static boolean validateWithExtXSDUsingSAX(String xml, String xsd) throws
ParserConfigurationException, IOException {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
SchemaFactory schemaFactory = null;
try {
schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
} catch (Exception e) {
System.out.println("schema factory error" + e.getMessage());
}
SAXParser parser = null;
try {
factory.setSchema(schemaFactory.newSchema(new Source[] { new StreamSource(xsd) }));
parser = factory.newSAXParser();
} catch (SAXException se) {
System.out.println("SCHEMA : " + se.getMessage()); // problem in
// the XSD
// itself
return false;
}
XMLReader reader = parser.getXMLReader();
reader.setErrorHandler(
new ErrorHandler() {
public void warning(SAXParseException e) throws SAXException {
System.out.println("WARNING: " + e.getMessage()); // do
// nothing
}
public void error(SAXParseException e) throws SAXException {
System.out.println("ERROR : " + e.getMessage());
throw e;
}
public void fatalError(SAXParseException e) throws SAXException {
System.out.println("FATAL : " + e.getMessage());
throw e;
}
});
reader.parse(new InputSource(xml));
return true;
} catch (ParserConfigurationException pce) {
throw pce;
} catch (IOException io) {
throw io;
} catch (SAXException se) {
return false;
}
}
EDITAR :
Hay algunos problemas con el validador XML de Java incluido en las versiones originales de Android. Puede intentar usar Xerces en su lugar, puede descargarlo aquí:
http://code.google.com/p/xerces-for-android/
Aunque no hay descargas en la sección de descargas, puede hacer una comprobación de SVN para descargar el código fuente.
Enlace para descargar el archivo jar xerces-for-android.jar del repositorio de google.
Si el enlace de arriba no está disponible, use esta página para descargar: xerces