Generare classi Java da.File XSD...?


Ho un gigantesco SDK QuickBooks .File di schema XSD che definisce le richieste/risposte XML che posso inviare / ricevere da QuickBooks.

Mi piacerebbe essere in grado di generare facilmente classi Java da questi .File XSD, che potrei quindi utilizzare per eseguire il marshalling di XML in oggetti Java e oggetti Java in XML.

C'è un modo semplice per farlo...?

Idealmente, non richiederebbe librerie esterne alla distribuzione Java di base in fase di esecuzione. Ma sono flessibile...

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

13 answers

JAXB fa ESATTAMENTE quello che vuoi. È integrato nel JRE / JDK a partire da 1.6

 117
Author: basszero, 2011-08-30 19:54:14

Per espandere i commenti" usa JAXB " sopra,

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

Ad es., "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

Aspetta un po', e se hai un file XSD ben formato, otterrai alcune classi Java ben formate

 110
Author: Ed Norris, 2011-08-30 19:49:14

Se si desidera avviare la codifica da Java a XML e da XML a Java in meno di 5 minuti, provare la serializzazione XML semplice. Non passare ore ad imparare l'API JAXB http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

Tuttavia, se sei davvero appassionato di imparare JAXB, ecco un eccellente tutorial http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

Contenuto del tutorial:

JAXB per semplice serializzazione Java-XML

Ci sono un certo numero di modi per fare la serializzazione XML in Java. Se si desidera un controllo a grana fine sull'analisi e la serializzazione, è possibile utilizzare SAX, DOM o Stax per prestazioni migliori. Eppure, quello che spesso voglio fare è una semplice mappatura tra POJO e XML. Tuttavia, la creazione di classi Java per eseguire manualmente l'analisi degli eventi XML non è banale. Recentemente ho trovato che JAXB è una mappatura o serializzazione Java-XML rapida e conveniente.

JAXB contiene molto di funzioni utili, è possibile controllare l'implementazione di riferimento qui. Il blog di Kohsuke è anche una buona risorsa per saperne di più su JAXB. Per questo blog, ti mostrerò come fare una semplice serializzazione Java-XML con JAXB.

Da POJO a XML

Diciamo che ho un oggetto Java Item. Voglio serializzare un oggetto Item in formato XML. Quello che devo fare prima è annotare questo POJO con alcune annotazioni XML da javax.XML.legare.annotazione.* pacchetto. Vedere codice listato 1 per articolo.java

Dal codice

  • @XmlRootElement(name="Item") indica che voglio essere l'elemento radice.
  • @XmlType(propOrder = {"name", "price"}) indica l'ordine in cui voglio che l'elemento sia disposto nell'output XML.
  • @XmlAttribute(name="id", ...) indica che id è un attributo dell'elemento root.
  • @XmlElement(....) indica che voglio che il prezzo e il nome siano elementi all'interno dell'elemento.

Il mio Item.java è pronto. Posso quindi andare avanti e creare script JAXB per il marshalling 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"));

Per l'elenco completo dei codici, vedere l'elenco dei codici 2 main.java. Viene creato il file Listato 3 item.xml del codice di output. Assomiglia a questo:

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

Facile giusto? In alternativa, puoi canalizzare l'output XML come stringa di testo, Stream, Writer, ContentHandler, ecc...) metodo come

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

Invertiamo il processo. Supponiamo che ora abbia un pezzo di dati stringa XML e voglio trasformalo in Oggetto.oggetto java. I dati XML (codice listato 3) sono simili a

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

Posso quindi unmarshal questo codice xml per oggetto Item da

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

Per l'elenco completo del codice si prega di consultare il codice Listato 2 (principale.Java). La sorgente XML può venire in molte forme sia da Stream che da file. L'unica differenza, ancora una volta, è il parametro del metodo:

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

Validazione con Schema XML

L'ultima cosa che voglio menzionare qui è la convalida di input XML con schema prima unmarshalling all'oggetto Java. Creo un file di schema XML chiamato item.sda. Per l'elenco completo del codice si prega di consultare il codice Elenco 4 (Articolo.xsd). Ora quello che devo fare è registrare questo schema per la convalida.

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

Quando provo a unmarshal dati XML a POJO, se l'XML di input non è conforme allo schema, verrà rilevata un'eccezione. Per l'elenco completo del codice, vedere l'elenco del codice 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'.]

Qui cambio l'attributo ' id ' in string invece di intero.

Se l'input XML è valido rispetto allo schema, i dati XML verranno rimossi dall'elemento.oggetto java con successo.

 35
Author: Aries McRae, 2017-03-30 18:27:13

Utilizzando Eclipse IDE:-

  1. copia l'xsd in un progetto nuovo/esistente.
  2. Assicurati di avere JAXB JAR richiesti nel tuo classpath. È possibile scaricare uno qui .
  3. Fare clic destro sul file XSD -> Genera - > Classi JAXB.
 28
Author: Kumar Sambhav, 2013-03-15 11:55:30

XMLBeans lo farà. In particolare il comando "scomp".

EDIT: XMLBeans è stato ritirato, controlla questo post di stackoverflow per maggiori informazioni.

 14
Author: TofuBeer, 2017-05-23 11:33:13

Maven può essere utilizzato per lo scopo, è necessario aggiungere alcune dipendenze e pulire semplicemente l'applicazione. Otterrete tutte le classi create automaticamente nella cartella di destinazione.

Basta copiarli dal bersaglio al luogo desiderato, ecco pom.xml che ho usato per creare classed da file 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>

Basta posizionare i file xsd sotto "src/main/webapp/schemas/" e maven li troverà in fase di compilazione.

Spero che questo ti aiuti, maggiori informazioni possono essere trovate su http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html

Spero che possa aiutare:)

 12
Author: neel4soft, 2013-04-29 06:53:59

Il modo più semplice è usare la riga di comando. Basta digitare nella directory del vostro .file xsd:

xjc myFile.xsd.

Quindi, java genererà tutti i Pojo.

 12
Author: Willian Crozeta, 2016-08-12 15:17:13

L'opzione migliore è %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

Ho anche una domanda se abbiamo un'opzione per fare reverse engineering qui. se sì possiamo generare xsd dalla classe pojo?

 7
Author: sree, 2011-11-30 23:48:28

Se non ti dispiace usare una libreria esterna, ho usato Castor per farlo in passato.

 7
Author: Marc Novakowski, 2015-09-21 10:58:48

Limitazione JAXB.

Ho lavorato su JAXB, secondo la mia opinione è un bel modo di trattare i dati tra oggetti XML e Java. I lati positivi sono la sua comprovata e migliore in termini di prestazioni e controllo sui dati durante il runtime. Con un buon uso di strumenti o script costruiti porterà via molti sforzi di codifica.

Ho scoperto che la parte di configurazione non è un'attività immediata e ho passato ore a configurare l'ambiente di sviluppo.

Tuttavia ho lasciato cadere questo soluzione a causa di una stupida limitazione che ho affrontato. La mia definizione di schema XML (XSD ) ha un attributo/elemento con nome "valore" e che devo usare XSD così com'è. Questo piccolo vincolo ha costretto il mio passaggio di binding XJC a fallire con un errore "Property' Value ' già usato."

Ciò è dovuto all'implementazione JAXB, il processo di associazione tenta di creare oggetti Java da XSD aggiungendo pochi attributi a ciascuna classe e uno di essi è un attributo value. Quando ha elaborato il mio XSD si è lamentato che c'è già una proprietà con quel nome.

 5
Author: RAm, 2010-04-27 15:34:11

Non è XJC di JAXB è una possibile risposta a questo? Sto cercando di ottenere la stessa cosa. Ancora nella fase di "provare" però. Mi sono imbattuto in XJC, quindi ho pensato di condividere.

 4
Author: Nikhil, 2010-04-01 13:24:56

Il noto JAXB

C'è un plugin maven che potrebbe farlo per te in qualsiasi fase di compilazione che desideri.

Puoi fare queste cose in entrambi i modi: xsd Java

 2
Author: François Wauquier, 2011-08-30 19:59:40

Parlando della limitazione JAXB, una soluzione quando si ha lo stesso nome per attributi diversi è l'aggiunta di personalizzazioni jaxb in linea all'xsd:

+

. . dichiarazioni vincolanti . .

O personalizzazioni esterne...

Puoi vedere ulteriori informazioni su : http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

 1
Author: Nady, 2011-08-30 19:59:19