web-dev-qa-db-ja.com

.XSDファイルからJavaクラスを生成します...?

QuickBooksから送受信できるXML要求/応答を定義する巨大なQuickBooks SDK .XSDスキーマファイルがあります。

これらの.XSDファイルからJavaクラスを簡単に生成できるようにしたいので、XMLをJavaオブジェクトとJavaにマーシャリングするために使用できます。 XMLへのオブジェクト。

これを行う簡単な方法はありますか...?

理想的には、実行時に基本Javaディストリビューションの外部にあるライブラリを必要としません。しかし、私は柔軟です...

120

JAXB は、必要なことを正確に行います。 1.6からJRE/JDKに組み込まれています

118
basszero

上記の「JAXBを使用」コメントを展開するには、

Windowsの場合"%Java_home%\bin\xjc" -p [your namespace] [xsd_file].xsd

例:"%Java_home%\bin\xjc" -p com.mycompany.quickbooks.obj quickbooks.xsd

少し待ってください。整形式のXSDファイルがあれば、整形式のJavaクラスを取得できます

116
Ed Norris

5分以内にJavaをXMLに、XMLをJavaにコーディングし始める場合は、Simple XML Serializationを試してください。 JAXB APIの学習に時間を費やさないでください http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php

ただし、JAXBの学習に本当に熱心な場合は、優れたチュートリアルをご覧ください http://blogs.Oracle.com/teera/entry/jaxb_for_simple_Java_xml

チュートリアルの内容:

単純なJava-XMLシリアル化のためのJAXB

JavaでXMLシリアル化を行う方法はいくつかあります。解析とシリアル化をきめ細かく制御したい場合は、パフォーマンスを向上させるためにSAX、DOM、またはStaxを使用できます。それでも、私がやりたいことは、POJOとXMLの間の単純なマッピングです。ただし、XMLイベントの解析を手動で行うJavaクラスを作成するのは簡単ではありません。私は最近、JAXBが迅速で便利なJava-XMLマッピングまたはシリアル化であることを発見しました。

JAXBには多くの便利な機能が含まれています。参照実装はこちらで確認できます。 Kohsukeのブログ は、JAXBについてさらに学ぶための優れたリソースでもあります。このブログエントリでは、JAXBを使用して簡単なJava-XMLシリアル化を行う方法を紹介します。

POJOからXML

Item Javaオブジェクトがあるとします。 ItemオブジェクトをXML形式にシリアル化したい。最初にやらなければならないのは、このPOJOにjavax.xml.bind.annotation。*パッケージのいくつかのXMLアノテーションを付けることです。 Item.Javaのコードリスト1を参照してください。

コードから

  • @XmlRootElement(name="Item")は、ルート要素になりたいことを示します。
  • @XmlType(propOrder = {"name", "price"})は、要素をXML出力に配置する順序を示します。
  • @XmlAttribute(name="id", ...)は、idがルート要素の属性であることを示します。
  • @XmlElement(....)は、価格と名前がItem内の要素であることを示します。

Item.Javaの準備ができました。次に、アイテムをマーシャリングするためのJAXBスクリプトを作成します。

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

完全なコードリストについては、コードリスト2 main.Javaを参照してください。出力コードリスト3 item.xmlファイルが作成されます。次のようになります。

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

簡単でしょう?あるいは、次のようにmarshal(...)メソッドのパラメーターを変更するだけで、出力XMLをテキスト文字列、ストリーム、ライター、ContentHandlerなどとしてチャネリングできます。

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

プロセスを逆にしましょう。今、XML文字列データの断片があり、それをItem.Javaオブジェクトに変換したいとします。 XMLデータ(コードリスト3)は次のようになります

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

次に、このxmlコードをItemオブジェクトに非整列化します。

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

完全なコードリストについては、コードリスト2(main.Java)を参照してください。 XMLソースは、ストリームとファイルの両方から多くの形式で提供されます。唯一の違いは、メソッドパラメータです。

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

XMLスキーマによる検証

ここで最後に言及したいのは、Javaオブジェクトへの非整列化の前にスキーマで入力XMLを検証することです。 item.xsdというXMLスキーマファイルを作成します。完全なコードリストについては、コードリスト4(Item.xsd)を参照してください。次に、このスキーマを検証用に登録する必要があります。

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

XMLデータをPOJOに非整列化しようとすると、入力XMLがスキーマに準拠していない場合、例外がキャッチされます。完全なコードリストについては、コードリスト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'.]

ここでは、「id」属性を整数ではなく文字列に変更します。

XML入力がスキーマに対して有効な場合、XMLデータはItem.Javaオブジェクトに正常に非整列化されます。

37
Aries McRae

Eclipse IDEの使用:-

  1. xsdを新しい/既存のプロジェクトにコピーします。
  2. クラスパスにJAXBが必要なJARがあることを確認してください。 1つ こちら をダウンロードできます。
  3. XSDファイルを右クリック->生成-> JAXBクラス。
29
Kumar Sambhav

最も簡単な方法は、コマンドラインを使用することです。 .xsdファイルのディレクトリに入力するだけです:

xjc myFile.xsd.

したがって、JavaはすべてのPojoを生成します。

16
Willian Crozeta

XMLBeans はそれを行います。具体的には「scomp」コマンド。

編集:XMLBeansは 非推奨 になりました。詳細は this stackoverflow post を確認してください。

14
TofuBeer

Mavenはこの目的に使用できます。いくつかの依存関係を追加して、アプリケーションをクリーンアップする必要があります。ターゲットフォルダにすべてのクラスが自動的に作成されます。

それらをターゲットから目的の場所にコピーするだけです。これは、xsdファイルからクラス化された作成に使用したpom.xmlです。

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

Xsdファイルを「src/main/webapp/schemas /」の下に置くだけで、mavenはコンパイル時にそれらを見つけます。

これがお役に立てば幸いです。詳細については http://www.beingjavaguys.com/2013/04/create-spring-web-services-using-maven.html をご覧ください。

それが役立つことを願っています:)

12
neel4soft

外部ライブラリを使用してもかまわないのであれば、過去にこれを行うために Castor を使用しました。

7
Marc Novakowski

最適なオプションは%Java_home%\bin\xjc -p [your namespace] [xsd_file].xsdです。

ここでリバースエンジニアリングを行うオプションがあるかどうかについても質問があります。はいの場合、pojoクラスからxsdを生成できますか?

7
sree

JAXBの制限。

私の意見では、XMLオブジェクトとJavaオブジェクト間のデータを処理する素晴らしい方法であるJAXBに取り組みました。プラス面は、実績があり、パフォーマンスが向上し、実行時にデータを制御できることです。ビルドされたツールまたはスクリプトを適切に使用すると、多くのコーディング作業が不要になります。

構成部分はすぐに実行できるタスクではなく、開発環境をセットアップするのに何時間も費やしました。

しかし、私が直面したばかげた制限のために、このソリューションを削除しました。私のXMLスキーマ定義(XSD)には「値」という名前の属性/要素があり、XSDをそのまま使用する必要があります。この非常に小さな制約により、バインディングプロパティXJCは「プロパティ '値'が既に使用されています」というエラーで失敗しました。

これはJAXB実装が原因で、バインディングプロセスは各クラスにいくつかの属性を追加することでXSDからJavaオブジェクトを作成しようとし、その1つが値属性になります。 XSDを処理したときに、その名前のプロパティが既に存在するという苦情がありました。

5
RAm

JAXBのXJCはこれに対する可能な答えではありませんか?私は同じことを達成しようとしています。ただし、まだ「試行」段階です。 XJCに出くわしたので、共有することを考えました。

4
Nikhil

よく知られている JAXB

mavenプラグイン があり、必要なビルドフェーズでこれを行うことができます。

あなたは両方の方法でこれを行うことができます:xsd <-> Java

2

JAXBの制限について言えば、異なる属性に同じ名前を使用する場合の解決策は、xsdにインラインjaxbカスタマイズを追加することです。

+

。 。バインディング宣言。 。

または外部のカスタマイズ...

詳細については、次を参照してください: http://jaxb.Java.net/tutorial/section_5_3-Overriding-Names.html

1
Nady