2009-03-26 56 views
110

Tengo un gigantesco archivo de esquema QuickBooks SDK .XSD que define solicitudes/respuestas XML que puedo enviar/recibir de QuickBooks.Generar clases de Java a partir de archivos .XSD ...?

Me gustaría poder generar fácilmente clases de Java a partir de estos archivos .XSD, que luego podría usar para ordenar objetos XML a Java y objetos Java a XML.

¿Hay una manera fácil de hacer esto ...?

Idealmente, no requeriría ninguna biblioteca externa a la distribución Java básica en tiempo de ejecución. Pero soy flexible ...

+5

Si quieres generación manual, colocar el archivo .xsd en su proyecto Eclipse, haga clic derecho en el archivo, después haga clic en "generar" –

Respuesta

113

JAXB hace EXACTAMENTE lo que quiere. Está integrado en el JRE/JDK a partir de 1.6

+5

Por desgracia, esta funcionalidad ya no estará disponible a partir del 9 de Java Esto se debe a que las clases involucradas (en particular, las clases com.sun.tools.xjc. *) Ya no estarán disponibles a través del JDK. – Marco

+1

No creo que la eliminación de esto del JDK sea un problema, porque el proyecto java.net (vinculado en la respuesta) probablemente se quede. – stmoebius

14

XMLBeans lo haré. Específicamente el comando "scomp".

EDITAR: XMLBeans ha sido retired, consulte this stackoverflow post para obtener más información.

+2

Sí, pero XMLBeans ha sido descontinuado. – stmoebius

+0

http://stackoverflow.com/questions/27727546/what-to-use-instead-of-xmlbeans-now-that-it-has-been-retired – TofuBeer

7

Si no te importa usar una biblioteca externa, he usado Castor para hacer esto en el pasado.

+0

Si genera código con Castor, ¿esas clases generadas aún dependen de Caster después del hecho? ¿O podría mover esas clases a una máquina sin las bibliotecas de Castor, y todavía funcionarían? –

+0

No, las clases generadas no dependen de las bibliotecas de Castor. – dave

+0

¿Hay buenos tutoriales sobre cómo usar Castor para hacer esto? Parece muy prometedor ... pero Java es, por decir lo menos, no mi lenguaje más fuerte. No estoy seguro de qué archivos/paquetes de Castor necesito descargar y cómo hacer la generación de código ... ¿algún ejemplo de novato paso a paso? –

2

el conocido JAXB

Hay una maven plugin que podría hacer esto para usted en cualquier fase de construcción que desee.

que podría hacer estas cosas en ambos sentidos: xsd < -> Java

35

Si quieres empezar a programar en Java para XML y XML para Java en menos de 5 minutos, trate de serialización XML simple. No pasar horas aprendiendo la API JAXB http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

Sin embargo, si usted está realmente interesado en aprender JAXB, aquí hay un excelente tutorial http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

Contenido del tutorial:

JAXB para Simple Servicación Java-XML

Hay una serie de forma de hacer la serialización XML en Java. Si desea un control detallado sobre el análisis y la serialización, puede optar por SAX, DOM o Stax para obtener un mejor rendimiento. Sin embargo, lo que a menudo quiero hacer es un mapeo simple entre POJO y XML. Sin embargo, la creación de clases Java para realizar el análisis de eventos XML manualmente no es trivial. Recientemente descubrí que JAXB es una asignación o serialización Java-XML rápida y conveniente.

JAXB contiene muchas funciones útiles, puede consultar la implementación de referencia aquí. Kohsuke's Blog es también un buen recurso para aprender más sobre JAXB. Para esta entrada de blog, le mostraré cómo hacer una simple serialización Java-XML con JAXB.

POJO a XML

Digamos que tiene un objeto de Java artículo. Quiero serializar un objeto Item a formato XML. Lo que tengo que hacer primero es anotar este POJO con algunas anotaciones XML del paquete javax.xml.bind.annotation. *. Vea el código que enumera 1 para el artículo.java

A partir del código

  • @XmlRootElement(name="Item") indica que yo quiero ser el elemento raíz.
  • @XmlType(propOrder = {"name", "price"}) indica el orden en que quiero que el elemento se organice en salida XML.
  • @XmlAttribute(name="id", ...) indica que id es un atributo para el elemento raíz.
  • @XmlElement(....) indica que deseo que el precio y el nombre sean elementos dentro del artículo.

Mi Item.java está listo. Luego puedo seguir y crear un script JAXB para ordenar el artículo.

//creating Item data object 
Item item = new Item(); 
item.setId(2); 
item.setName("Foo"); 
item.setPrice(200); 
..... 

JAXBContext context = JAXBContext.newInstance(item.getClass()); 
Marshaller marshaller = context.createMarshaller(); 
//I want to save the output file to item.xml 
marshaller.marshal(item, new FileWriter("item.xml")); 

Por completo listado de código consulte Listado de Código 2 main.java. Se crea el archivo de código de salida 3 item.xml. Se ve así:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item"> 

<ns1:itemName>Foo</ns1:itemName> 
<ns1:price>200</ns1:price> 

</ns1:item> 

Fácil ¿verdad? Puede canalizar alternativamente el XML de salida como cadena de texto, Arroyo, escritor, ContentHandler, etc simplemente cambiar el parámetro del método Mariscal (...) como

... 
JAXBContext context = JAXBContext.newInstance(item.getClass()); 
Marshaller marshaller = context.createMarshaller(); 
// save xml output to the OutputStream instance 
marshaller.marshal(item, <java.io.OutputStream instance>); 

... 
JAXBContext context = JAXBContext.newInstance(item.getClass()); 
Marshaller marshaller = context.createMarshaller(); 
StringWriter sw = new StringWriter(); 
//save to StringWriter, you can then call sw.toString() to get java.lang.String 
marshaller.marshal(item, sw); 

XML para POJO

Let de revertir el proceso. Supongamos que ahora tengo una parte de datos de cadena XML y quiero convertirlo en objeto Item.java. datos XML (Listado de Código 3) parece

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns1:item ns1:id="2" xmlns:ns1="http://blogs.sun.com/teera/ns/item"> 
<ns1:itemName>Bar</ns1:itemName> 
<ns1:price>80</ns1:price> 
</ns1:item> 

puedo entonces unmarshal el código XML a objeto de artículos por

... 
ByteArrayInputStream xmlContentBytes = new ByteArrayInputStream (xmlContent.getBytes()); 
JAXBContext context = JAXBContext.newInstance(Item.getClass()); 
Unmarshaller unmarshaller = context.createUnmarshaller(); 
//note: setting schema to null will turn validator off 
unmarshaller.setSchema(null); 
Object xmlObject = Item.getClass().cast(unmarshaller.unmarshal(xmlContentBytes)); 
return xmlObject; 
... 

Para código completo consulte Listado de Código 2 (main.java). La fuente XML puede venir en muchas formas tanto de Stream como de archivo. La única diferencia, de nuevo, es el parámetro del método:

... 
unmarshaller.unmarshal(new File("Item.xml")); // reading from file 
... 
// inputStream is an instance of java.io.InputStream, reading from stream 
unmarshaller.unmarshal(inputStream); 

Validación con el esquema XML

Lo último que quiero mencionar aquí es la validación de entrada XML con el esquema antes unmarshalling al objeto Java. Creo un archivo de esquema XML llamado item.xsd. Para obtener el listado completo del código, consulte el Listado de Código 4 (Item.xsd). Ahora lo que tengo que hacer es registrar este esquema para la validación.

... 
Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) 
.newSchema(new File("Item.xsd")); 
unmarshaller.setSchema(schema); //register item.xsd shcema for validation 
... 

Cuando trato de datos XML unmarshal a POJO, si el XML de entrada no está conforme con el esquema, serán capturados excepción. Para obtener el listado completo del código, consulte el Listado de Código 5 (invalid_item.xml).

javax.xml.bind.UnmarshalException 
- with linked exception: 
javax.xml.bind.JAXBException caught: null 
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: 'item1' is 
           not a valid value for 'integer'.] 

Aquí cambio el atributo 'id' a cadena en lugar de entero.

Si la entrada XML es válida frente al esquema, los datos XML se desmarcarán correctamente al objeto Item.java.

+1

Esto se ve * muy * prometedor, y es mucho más simple y agradable trabajar para lo que necesito que algo grande y complicado como JAXB. Desafortunadamente, no veo ninguna forma de convertir mi .XSD existente a archivos .class, que es realmente lo que necesito para comenzar. ¿Hay alguna forma de hacer esto? –

+6

Desafortunadamente, el blog con el Tutorial JAXB está fuera de línea. –

+0

podemos hacerlo fácilmente usando jaxb2-maven-plugin, comprobar este tutorial http://www.journaldev.com/1312/how-to-generate-java-classes-from-xsd-using-xjc-maven-plugin – Pankaj

4

¿No es el XJC de JAXB una posible respuesta a esto?Estoy tratando de lograr lo mismo. Aún en la fase de "prueba" sin embargo. Encontré XJC, así que pensé en compartir.

5

JAXB Limitación.

Trabajé en JAXB, según mi opinión es una buena forma de tratar los datos entre objetos XML y Java. Los lados positivos están comprobados y son mejores en rendimiento y control sobre los datos durante el tiempo de ejecución. Con un buen uso de herramientas o scripts integrados, se eliminarán muchos esfuerzos de codificación.

Encontré que la parte de configuración no es una tarea directa, y pasé horas en obtener la configuración del entorno de desarrollo.

Sin embargo, se me cayó esta solución debido a una limitación tonta que enfrenté. Mi definición de esquema XML (XSD) tiene un atributo/elemento con el nombre "valor" y tengo que usar XSD tal como está. Esta muy pequeña restricción obligó a mi enlace de enlace XJC falló con un error "Propiedad 'Valor' ya utilizado".

Esto se debe a la implementación de JAXB, el proceso de enlace intenta crear objetos de Java a partir de XSD agregando algunos atributos a cada clase y uno de ellos es un atributo de valor. Cuando procesó mi XSD se quejó de que ya hay una propiedad con ese nombre.

105

para ampliar el "uso" JAXB comentarios anteriores,

En Windows "%java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd

por ejemplo, "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

esperar un poco, y si tenía un archivo XSD bien formado, usted conseguirá algunas clases de Java bien formados

6

Bueno mejor opción es %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

También tengo una pregunta si tenemos la opción de realizar ingeniería inversa aquí. Si es así, ¿podemos generar xsd de la clase pojo?

+0

xjc está disponible solo en java6 – sree

26

Usando Eclipse IDE: -

  1. copia del xsd en un proyecto nuevo/existente.
  2. Asegúrate de tener JAR requeridos por JAXB en tu classpath. Puede descargar uno here.
  3. Haga clic con el botón derecho en el archivo XSD -> Generar -> clases JAXB.
12

Maven se puede utilizar para tal fin, necesita agregar algunas dependencias y simplemente limpiar su aplicación. Obtendrá todas las clases creadas automáticamente en su carpeta de destino.

sólo tiene que copiarlos a partir de destino a su lugar deseado, aquí es pom.xml que he utilizado para crear clasificado a partir de archivos xsd:

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>jaxb2-maven-plugin</artifactId> 

    <executions> 
     <execution> 
     <goals> 
     <goal>xjc</goal> 
     </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <schemaDirectory>src/main/webapp/schemas/</schemaDirectory> 
    </configuration> 
    </plugin> 

    </plugins> 
    </pluginManagement> 
</build> 
</project> 

Sólo tiene que colocar sus archivos XSD en "src/main/webapp/esquemas/"y maven los encontrará en tiempo de compilación.

Hope esto le ayudará, más información se puede encontrar en http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html

esperan que ayude :)

+0

¿Esto realmente funciona con el directorio de recursos? (src/main/resources/schemas), porque sigo obteniendo esto: 'No se encontraron archivos XSD. Por favor, comprueba la configuración de tu complemento. – zygimantus

11

la forma más fácil es usar la línea de comandos. Simplemente escriba en el directorio de su archivo .xsd:

xjc myFile.xsd. 

Por lo tanto, la java generará todos los Pojos.

Cuestiones relacionadas