Estoy generando algunos archivos xml que deben ajustarse a un archivo xsd que me dieron. ¿Cuál es la mejor manera de verificar que cumplen?
fuente
Estoy generando algunos archivos xml que deben ajustarse a un archivo xsd que me dieron. ¿Cuál es la mejor manera de verificar que cumplen?
La biblioteca de tiempo de ejecución Java admite validación. La última vez que revisé esto fue el analizador Apache Xerces debajo de las cubiertas. Probablemente deberías usar un javax.xml.validation.Validator .
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd:
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}
La constante de fábrica del esquema es la cadena http://www.w3.org/2001/XMLSchema
que define los XSD. El código anterior valida un descriptor de despliegue WAR contra la URLhttp://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
pero podría validarlo fácilmente con un archivo local.
No debe usar DOMParser para validar un documento (a menos que su objetivo sea crear un modelo de objeto de documento de todos modos). Esto comenzará a crear objetos DOM a medida que analiza el documento, un desperdicio si no los va a usar.
Aquí se explica cómo hacerlo con Xerces2 . Un tutorial para esto, aquí (solicitud de registro).
Atribución original: copiada descaradamente de aquí :
fuente
Construimos nuestro proyecto usando ant, por lo que podemos usar la tarea de validación de esquema para verificar nuestros archivos de configuración:
¡Ahora los archivos de configuración traviesos fallarán en nuestra compilación!
http://ant.apache.org/manual/Tasks/schemavalidate.html
fuente
Dado que esta es una pregunta popular, señalaré que Java también puede validar contra xsd "referidos", por ejemplo, si el archivo .xml en sí mismo especifica XSD en el encabezado, usando
xsi:SchemaLocation
oxsi:noNamespaceSchemaLocation
(o xsi para espacios de nombres particulares) ej :o SchemaLocation (siempre una lista de asignaciones de espacio de nombres a xsd)
Las otras respuestas también funcionan aquí, porque los archivos .xsd "se asignan" a los espacios de nombres declarados en el archivo .xml, porque declaran un espacio de nombres, y si coincide con el espacio de nombres en el archivo .xml, está bien. Pero a veces es conveniente poder tener un resolutor personalizado ...
De los javadocs: "Si crea un esquema sin especificar una URL, un archivo o una fuente, el lenguaje Java crea uno que busca en el documento que se está validando para encontrar el esquema que debe usar. Por ejemplo:"
y esto funciona para múltiples espacios de nombres, etc. El problema con este enfoque es que
xmlsns:xsi
probablemente sea una ubicación de red, por lo que saldrá por defecto y llegará a la red con cada validación, no siempre óptima.Aquí hay un ejemplo que valida un archivo XML contra cualquier XSD al que hace referencia (incluso si tiene que extraerlo de la red):
Puede evitar extraer los XSD referenciados de la red, aunque los archivos xml hagan referencia a las URL, especificando el xsd manualmente (vea algunas otras respuestas aquí) o utilizando un resolutor de estilo "catálogo XML" . Spring aparentemente también puede interceptar las solicitudes de URL para servir archivos locales para validaciones. O puede configurar el suyo a través de setResourceResolver , por ejemplo:
Vea también aquí para otro tutorial.
Creo que el defecto es usar DOM análisis, se puede hacer algo similar con analizador SAX que está validando así
saxReader.setEntityResolver(your_resolver_here);
fuente
setResourceResolver
pero más allá de eso, tal vez abra una nueva pregunta ...Usando Java 7 puede seguir la documentación provista en la descripción del paquete .
fuente
parser.parse(new File("instance.xml"))
. Elvalidator
acepta unaSource
, para que pueda:validator.validate(new StreamSource(new File("instance.xml")))
.ErrorHandler
si necesita hacer la validación.Si tiene una máquina Linux, puede usar la herramienta gratuita de línea de comandos SAXCount. Esto me pareció muy útil.
Valida contra dtd y xsd. 5s para un archivo de 50MB.
En debian squeeze se encuentra en el paquete "libxerces-c-samples".
¡La definición de dtd y xsd debe estar en el xml! No puedes configurarlos por separado.
fuente
xmllint --schema phone.xsd phone.xml
(de una respuesta de 13ren)Una respuesta más: ya que dijiste que debes validar los archivos que estás generando (escribiendo), es posible que desee validar el contenido mientras escribe, en lugar de escribir primero y luego volver a leer para validar. Probablemente pueda hacer eso con la API JDK para la validación Xml, si usa un escritor basado en SAX: si es así, solo conecte el validador llamando a 'Validator.validate (fuente, resultado)', donde la fuente proviene de su escritor, y el resultado es donde la salida necesita ir.
Alternativamente, si usa Stax para escribir contenido (o una biblioteca que usa o puede usar stax), Woodstox también puede soportar directamente la validación cuando usa XMLStreamWriter. Aquí hay una entrada de blog que muestra cómo se hace:
fuente
Si está generando archivos XML mediante programación, puede consultar la biblioteca XMLBeans . Usando una herramienta de línea de comandos, XMLBeans generará y empaquetará automáticamente un conjunto de objetos Java basados en un XSD. Luego puede usar estos objetos para crear un documento XML basado en este esquema.
Tiene soporte incorporado para validación de esquemas y puede convertir objetos Java en un documento XML y viceversa.
Castor y JAXB son otras bibliotecas de Java que tienen un propósito similar a XMLBeans.
fuente
Con JAXB, puede usar el siguiente código:
fuente
¿Estás buscando una herramienta o una biblioteca?
En cuanto a las bibliotecas, el estándar de facto es Xerces2, que tiene versiones C ++ y Java .
Sin embargo, tenga en cuenta que es una solución de gran peso. Pero, de nuevo, validar XML contra archivos XSD es un problema bastante pesado.
En cuanto a una herramienta para hacer esto por usted, XMLFox parece ser una solución gratuita decente, pero no lo he usado personalmente, no puedo decir con certeza.
fuente
Validar contra esquemas en línea
Validar contra esquemas locales
Validación XML sin conexión con Java
fuente
Usando Woodstox , configure el analizador StAX para validar contra su esquema y analizar el XML.
Si se detectan excepciones, el XML no es válido; de lo contrario, es válido:
Nota : Si necesita validar varios archivos, debe intentar reutilizar su
XMLInputFactory
yXMLValidationSchema
para maximizar el rendimiento.fuente
Tuve que validar un XML contra XSD solo una vez, así que probé XMLFox. Lo encontré muy confuso y extraño. Las instrucciones de ayuda no parecían coincidir con la interfaz.
Terminé usando LiquidXML Studio 2008 (v6), que era mucho más fácil de usar y más familiarizado de inmediato (la interfaz de usuario es muy similar a Visual Basic 2008 Express, que uso con frecuencia). El inconveniente: la capacidad de validación no está en la versión gratuita, por lo que tuve que usar la prueba de 30 días.
fuente