Generar clases Java desde.Archivos XSD...?


Tengo un SDK de QuickBooks gigantesco .Archivo de esquema XSD que define las solicitudes/respuestas XML que puedo enviar / recibir de QuickBooks.

Me gustaría poder generar fácilmente clases Java a partir de estas .Archivos XSD, que luego podría usar para combinar XML con objetos Java, y objetos Java con XML.

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

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

 117
Author: Keith Palmer Jr., 2009-03-26

13 answers

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

 117
Author: basszero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-30 19:54:14

Para ampliar los comentarios anteriores sobre" usar JAXB",

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

E. g., "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

Espere un poco, y si tiene un archivo XSD bien formado, obtendrá algunas clases Java bien formadas

 110
Author: Ed Norris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-30 19:49:14

Si desea comenzar a codificar Java a XML y XML a Java en menos de 5 minutos, pruebe la serialización XML Simple. No pases horas aprendiendo la API de JAXB http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

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

Contenido del tutorial:

JAXB para serialización simple de Java-XML

Hay varias formas 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 un mejor rendimiento. Sin embargo, lo que a menudo quiero hacer es un mapeo simple entre POJOs y XML. Sin embargo, crear clases Java para hacer análisis de eventos XML manualmente no es trivial. Recientemente descubrí que JAXB es un mapeo o serialización Java-XML rápido y conveniente.

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

POJO a XML

Digamos que tengo un objeto Java Item. Quiero serializar un objeto Item en formato XML. Lo que tengo que hacer primero es anotar este POJO con algunas anotaciones XML de javax.XML.unir.anotación.* paquete. Ver listado de código 1 para el artículo.java

Del código

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

Mi Item.java está listo. Entonces puedo seguir adelante y crear script JAXB para marshaling Elemento.

//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"));

Para una lista de códigos completa, véase la Lista de códigos 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? Alternativamente, puede canalizar el XML de salida como cadena de texto, Secuencia, Escritor, controlador de contenido, etc. simplemente cambie el parámetro del marshal(...) método 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 a POJO

Vamos a invertir el proceso. Supongamos que ahora tengo una pieza de datos de cadena XML y quiero conviértelo en Objeto.objeto java. Los datos XML (Listado de código 3) parecen

<?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>

Entonces puedo desmarcar este código xml al objeto Item mediante

...
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 una lista de códigos completa, consulte la Lista de códigos 2 (principal.Java). La fuente XML puede venir en muchas formas tanto de Flujo 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 esquema XML

Lo último que quiero mencionar aquí es validar XML de entrada con esquema antes unmarshalling a Java object. Creo un archivo de esquema XML llamado item.xsd. Para una lista completa de códigos, consulte la Lista de códigos 4 (Artículo.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 intento deserializar datos XML a POJO, si el XML de entrada no se ajustaba al esquema de excepción serán atrapados. Para una lista completa de códigos, consulte la Lista de códigos 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 string en lugar de entero.

Si la entrada XML es válida para el esquema, los datos XML no estarán marcados en Item.objeto java con éxito.

 35
Author: Aries McRae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-30 18:27:13

Usando Eclipse IDE: -

  1. copie el xsd en un proyecto nuevo/existente.
  2. Asegúrate de tener JAXB jars requeridos en tu classpath. Puede descargar uno aquí.
  3. Haga clic derecho en el archivo XSD -> Generar -> clases JAXB.
 28
Author: Kumar Sambhav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-15 11:55:30

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

EDITAR: XMLBeans ha sido retirado, revisa este post de stackoverflow para más información.

 14
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:13

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

Simplemente cópielos del destino al lugar deseado, aquí está pom.xml que he usado para crear archivos xsd clasificados:

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

Simplemente coloque sus archivos xsd en "src/main/webapp/schemas/" y maven los encontrará en tiempo de compilación.

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

Espero que ayude:)

 12
Author: neel4soft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-29 06:53:59

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.

Entonces, java generará todos los Pojos.

 12
Author: Willian Crozeta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-12 15:17:13

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

También tengo una pregunta si tenemos una opción para hacer ingeniería inversa aquí. en caso afirmativo, ¿podemos generar xsd a partir de la clase pojo?

 7
Author: sree,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-30 23:48:28

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

 7
Author: Marc Novakowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-21 10:58:48

Limitación JAXB.

Trabajé en JAXB, según mi opinión es una buena manera de tratar con los datos entre XML y objetos Java. Los aspectos positivos son su probada y mejor en rendimiento y control sobre los datos durante el tiempo de ejecución. Con un buen uso de herramientas o scripts construidos, se quitará muchos esfuerzos de codificación.

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

Sin embargo, se me cayó esto solución debido a una limitación tonta que enfrenté. Mi Definición de Esquema XML (XSD ) tiene un atributo/elemento con el nombre "value" y que tengo que usar XSD tal cual. Esta muy pequeña restricción forzó el paso mi 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 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ó que ya hay una propiedad con ese nombre.

 5
Author: RAm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-27 15:34:11

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

 4
Author: Nikhil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-04-01 13:24:56

El conocido JAXB

Hay un complemento maven que podría hacer esto por usted en cualquier fase de compilación que desee.

Puedes hacer esto de ambas maneras: xsd Java

 2
Author: François Wauquier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-30 19:59:40

Hablando de la limitación JAXB, una solución cuando se tiene el mismo nombre para diferentes atributos es agregar personalizaciones jaxb en línea al xsd:

+

. . declaraciones vinculantes . .

O personalizaciones externas...

Puede ver más información en : http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

 1
Author: Nady,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-30 19:59:19