Générer des classes Java à partir de.Fichiers XSD??


J'ai un gigantesque SDK QuickBooks .Fichier de schéma XSD qui définit les demandes/réponses XML que je peux envoyer / recevoir de QuickBooks.

J'aimerais pouvoir générer facilement des classes Java à partir de celles-ci .Fichiers XSD, que je pourrais ensuite utiliser pour marshaler XML en objets Java, et les objets Java en XML.

Existe-t-il un moyen facile de le faire...?

Idéalement, il ne nécessiterait aucune bibliothèque externe à la distribution Java de base au moment de l'exécution. Mais je suis flexible...

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

13 answers

JAXB fait EXACTEMENT ce que vous voulez. Il est intégré dans le JRE / JDK à partir de 1.6

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

Pour développer les commentaires "utiliser JAXB" ci-dessus,

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

Par exemple, "%java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

Attendez un peu, et si vous aviez un fichier XSD bien formé, vous obtiendrez des classes Java bien formées

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

Si vous voulez commencer à coder Java en XML et XML en Java en moins de 5 minutes, essayez la sérialisation XML simple. Ne passez pas des heures à apprendre l'API JAXB http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

Cependant, si vous êtes vraiment désireux d'apprendre JAXB, voici un excellent tutoriel http://blogs.oracle.com/teera/entry/jaxb_for_simple_java_xml

Contenu du tutoriel:

JAXB pour la sérialisation Java-XML simple

Il existe plusieurs façons de faire la sérialisation XML en Java. Si vous voulez un contrôle précis sur l'analyse et la sérialisation, vous pouvez opter pour SAX, DOM ou Stax pour de meilleures performances. Pourtant, ce que je veux souvent faire est un simple mappage entre POJOs et XML. Cependant, la création de classes Java pour effectuer manuellement l'analyse d'événements XML n'est pas triviale. J'ai récemment trouvé que JAXB était un mappage ou une sérialisation Java-XML rapide et pratique.

JAXB contient beaucoup parmi les fonctionnalités utiles, vous pouvez consulter l'implémentation de référence ici. Le blog de Kohsuke est également une bonne ressource pour en savoir plus sur JAXB. Pour cette entrée de blog, je vais vous montrer comment faire une simple sérialisation Java-XML avec JAXB.

POJO au format XML

Disons que j'ai un objet Java Item. Je veux sérialiser un objet Item au format XML. Ce que je dois faire en premier, c'est annoter ce POJO avec quelques annotations XML de javax.XML.lier.annotation.* paquet. Voir code liste 1 pour l'article.java

Du code

  • @XmlRootElement(name="Item") indique que je veux être l'élément racine.
  • @XmlType(propOrder = {"name", "price"}) indique l'ordre dans lequel je veux que l'élément soit organisé en sortie XML.
  • @XmlAttribute(name="id", ...) indique que id est un attribut de l'élément racine.
  • @XmlElement(....) indique que je veux que le prix et le nom soient des éléments dans l'article.

Mon Item.java est prêt. Je peux ensuite aller de l'avant et créer un script JAXB pour le marshaling Article.

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

Pour la liste complète des codes, veuillez consulter la Liste des codes 2 main.java. Le code de sortie répertoriant le fichier 3 item.xml est créé. Cela ressemble à ceci:

<?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 non? Vous pouvez également canaliser le XML de sortie en tant que chaîne de texte, Flux, Écrivain, ContentHandler, etc. en modifiant simplement le paramètre du marshal(... méthode comme

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

Inversons le processus. Supposons que j'ai maintenant un morceau de données de chaîne XML et je veux transformez-le en article.objet java. Les données XML (liste de code 3) ressemblent à

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

Je peux ensuite décompresser ce code xml en objet Item par

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

Pour la liste complète des codes, veuillez consulter la liste des codes 2 (main.Java). La source XML peut prendre de nombreuses formes à la fois à partir d'un flux et d'un fichier. La seule différence, encore une fois, est le paramètre de méthode:

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

Validation avec le schéma XML

La dernière chose que je veux mentionner ici est de valider le XML d'entrée avec le schéma avant unmarshalling à l'objet Java. Je crée un fichier de schéma XML appelé item.xsd. Pour la liste complète des codes, veuillez consulter la liste des codes 4 (Article.xsd). Maintenant, ce que je dois faire est d'enregistrer ce schéma pour validation.

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

Lorsque j'essaie de décompresser les données XML vers POJO, si le XML d'entrée n'est pas conforme au schéma, une exception sera interceptée. Pour la liste complète des codes, veuillez consulter la liste des codes 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'.]

Ici, je change l'attribut ' id ' en chaîne au lieu de entier.

Si l'entrée XML est valide par rapport au schéma, les données XML seront décompressées dans Item.objet java avec succès.

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

Utilisation de l'E Eclipse: -

  1. copiez le xsd dans un projet nouveau/existant.
  2. Assurez-vous que vous avez JAXB required JARs dans votre classpath. Vous pouvez télécharger un ici.
  3. Faites un clic droit sur le fichier XSD -> Générer -> classes JAXB.
 28
Author: Kumar Sambhav, 2013-03-15 11:55:30

XMLBeans le fera. Plus précisément la commande "scomp".

EDIT: XMLBeans a étéretiré , vérifiezce post stackoverflow pour plus d'informations.

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

Maven peut être utilisé à cette fin, vous devez ajouter des dépendances et simplement nettoyer votre application. Vous obtiendrez toutes les classes créées automatiquement dans votre dossier cible.

Il suffit de les copier de la cible à l'endroit souhaité, voici pom.xml que j'ai utilisé pour créer classé à partir de fichiers 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>

Placez simplement vos fichiers xsd sous "src/main/webapp/schemas/" et maven les trouvera au moment de la compilation.

J'espère que cela vous aidera, plus d'informations peuvent être trouvées à http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html

J'espère que cela aidera:)

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

Le moyen le plus simple consiste à utiliser la ligne de commande. Il suffit de taper dans le répertoire de votre .fichier xsd:

xjc myFile.xsd.

Donc, le java générera tous les Pojos.

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

Eh bien la meilleure option est %java_home%\bin\xjc -p [your namespace] [xsd_file].xsd.

J'ai aussi une question si nous avons une option pour faire de la rétro-ingénierie ici. si oui, pouvons-nous générer xsd à partir de la classe pojo?

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

Si cela ne vous dérange pas d'utiliser une bibliothèque externe, j'ai utilisé Castor pour le faire dans le passé.

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

Limitation JAXB.

J'ai travaillé sur JAXB, selon mon avis, c'est une bonne façon de traiter les données entre les objets XML et Java. Les côtés positifs sont ses performances éprouvées et meilleures et le contrôle des données pendant l'exécution. Avec une bonne utilisation des outils ou des scripts construits, cela enlèvera beaucoup d'efforts de codage.

J'ai trouvé que la partie configuration n'est pas une tâche immédiate et j'ai passé des heures à configurer l'environnement de développement.

Cependant j'ai laissé tomber ceci solution en raison d'une limitation stupide à laquelle j'ai été confronté. Ma définition de schéma XML (XSD ) a un attribut/élément avec le nom "value" et que je dois utiliser XSD tel quel. Cette très petite contrainte a forcé l'échec de mon étape de liaison XJC avec une erreur "Propriété' Valeur ' déjà utilisée."

Cela est dû à l'implémentation JAXB, le processus de liaison essaie de créer des objets Java à partir de XSD en ajoutant quelques attributs à chaque classe et l'un d'eux étant un attribut value. Quand il a traité mon XSD il s'est plaint qu'il y a déjà une propriété avec ce nom.

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

Le XJC de JAXB n'est-il pas une réponse possible à cela? Je suis en train de réaliser la même chose. Toujours dans la phase" essayer " cependant. Je suis tombé sur XJC, alors j'ai pensé au partage.

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

Le bien-connu JAXB

Il existe un plugin maven qui pourrait le faire pour vous à n'importe quelle phase de construction que vous voulez.

Vous pouvez faire ce genre de choses dans les deux sens: xsd Java

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

En parlant de la limitation JAXB, une solution lorsque vous avez le même nom pour différents attributs est d'ajouter des personnalisations jaxb en ligne au xsd:

+

. . déclarations contraignantes . .

Ou des personnalisations externes...

Vous pouvez voir plus d'informations sur : http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html

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