.XSDファイルからJavaクラスを生成…


127

私は、QuickBooksから送受信できるXML要求/応答を定義する巨大なQuickBooks SDK .XSDスキーマファイルを持っています。

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

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

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


6
手動で生成する場合は、.xsdファイルをEclipseプロジェクトに配置し、ファイルを右クリックして、「生成」をクリックします
Junchen Liu

回答:


121

JAXBはまさにあなたが望むものを実行します。JRE / JDKに1.6以降で組み込まれています


7
残念ながら、この機能はJava 9以降では利用できなくなります。これは、関連するクラス(特に、com.sun.tools.xjc。*クラス)がJDK経由で利用できなくなるためです。
Marco

4
java.netプロジェクト(回答にリンクされている)はおそらく残っているので、JDKからこれを削除することは問題にならないと思います。
stmoebius

1
ここで説明するには、コマンドライン引数でのJava 9で依存関係を追加、または手動で依存関係を追加することができます。
Matthias Ronge

118

上記の「use 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クラスがいくつか得られます。


3
まことにありがとうございます!カプセル化されているのではなくトップレベルのクラスを生成するには、stackoverflow.com / questions / 13175224 / …を参照してください。クラス名の競合が発生する場合は、stackoverflow.com
明日

38

JavaからXMLおよびXMLからJavaへのコーディングを5分未満で開始したい場合は、シンプルなXMLシリアル化を試してください。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.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オブジェクトに非整列化されます。


1
これは非常に有望であり、JAXBのような大きくて複雑なものよりも、私が必要とするものを処理するのにはるかに単純で優れています。残念ながら、既存の.XSDを.classファイルに変換する方法はありません。これは、実際に開始する必要があるものです。これを行う方法はありますか?
キースパーマージュニア

7
残念ながら、JAXBチュートリアルのあるブログはオフラインです。
LuisC。

jaxb2-maven-pluginを使用して簡単に実行できます。このチュートリアルを確認してください。journaldev.com/ 1312 /…
Pankaj

""%java_home%\ bin \ xjc "-p [your namespace] [xsd_file] .xsd"の複雑な点は何ですか?
gorefest 2015年

30

Eclipse IDEの使用:-

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

17

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

xjc myFile.xsd.

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


14

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>

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

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

それが役に立てば幸い:)


1
これは実際にリソースディレクトリで機能しますか?(src / main / resources / schemas)、これを取得し続けるため:No XSD files found. Please check your plugin configuration.
zygimantus


7

よく最良のオプションは%java_home%\bin\xjc -p [your namespace] [xsd_file].xsdです。

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


xjcはjava6でのみ利用可能
sree

7

外部ライブラリを使用することを気にしない場合、私はこれまでCastorを使用してこれを行ってきました。


Castorを使用してコードを生成する場合、生成されたクラスは事後もCasterに依存していますか?または、Castorライブラリのないマシンにそれらのクラスを移動しても、それらは引き続き機能しますか?
キースパーマージュニア

いいえ、生成されたクラスはCastorライブラリーに依存していません。
デイブ

Castorを使用してこれを行う方法に関する優れたチュートリアルはありますか?それは非常に有望に見えます...しかし、Javaは、控えめに言っても、私の最強の言語ではありません。どのCastorファイル/パッケージをダウンロードする必要があるのか​​、実際にコードを生成する方法がわかりません。
キースパーマージュニア

Castor SourceGeneratorクラスの使用方法に関するドキュメントについては、このページをご覧ください:castor.org/sourcegen.html
Marc Novakowski

2
キャスターが長い死んでいるようだ...ドキュメントへのリンクはすべて404です
パヴェルVeselov

5

JAXBの制限。

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

構成の部分は簡単な作業ではなく、開発環境のセットアップに何時間も費やしました。

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

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


4

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



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.