Edited at

XMLSchema(xsdファイル)からJavaクラスを生成する

More than 3 years have passed since last update.

先日、JAXBを使用して、xmlファイルからJavaインスタンスを取得する処理を書くことがありました。この記事では、インスタンスのもとになるJavaクラスを、xsdファイル(XMLSchema)から自動生成する手順を説明します。


手順


  1. xsdファイル作成

  2. Javaクラス生成(xjcコマンド実行)

  3. xmlファイル作成 & xmlファイルからjavaインスタンス取得


1.xsdファイル作成

xsdファイルには、xmlの定義を記述します。JavaインスタンスにとってのJavaクラスのようなものです。以下でcars.xsdを例に、XMLSchemaについて説明します。


cars.xsd

<?xml version="1.0" encoding="UTF-8"?>

<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org/cars"
xmlns:tns="http://www.example.org/cars"
elementFormDefault="qualified">
<element name="cars">
<complexType>
<sequence>
<element ref="tns:car" minOccurs="1" maxOccurs="unbounded" />
</sequence>
</complexType>
</element>
<element name="car">
<complexType>
<sequence>
<element ref="tns:maker" minOccurs="1" maxOccurs="1" />
<element ref="tns:model" minOccurs="1" maxOccurs="1" />
</sequence>
<attribute name="number" type="string"/>
</complexType>
</element>
<element name="maker" type="string" />
<element name="model" type="string" />
</schema>

以下のcars.xmlは、上のxsdファイルに基づいて記述されたxmlファイルです。


cars.xml

<?xml version="1.0" encoding="UTF-8"?>

<cars xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/cars"
xsi:schemalocation="http://www.example.org/cars cars.xsd">
<car number="0001">
<maker>HONDA</maker>
<model>civic</model>
</car>
<car number="0002">
<maker>LOTUS</maker>
<model>elise</model>
</car>
</cars>


1.1.schema要素

名前空間を宣言します。


cars.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" 

targetNamespace="http://www.example.org/cars"
xmlns:tns="http://www.example.org/cars"
elementFormDefault="qualified">
<!-- 略 -->
</schema>


  • xmlns属性では、XMLSchema(xmlの定義)であることを宣言しています。

  • targetNameSpace属性では、このxsdファイルで記述する、xml定義の名前空間を宣言しています。

  • xmlns:tns属性では、tnsというプレフィックスと、このxsdファイルで記述する、xml定義の名前空間を結びつけています。targetNameSpace属性と同じである必要があります。


1.2.element要素~その1~

xmlの要素を定義します。ここでは、cars要素を定義しています。


cars.xsd

<!-- 略 -->

<element name="cars">
<complexType>
<sequence>
<element ref="tns:car" minOccurs="1" maxOccurs="unbounded" />
</sequence>
</complexType>
</element>
<!-- 略 -->


  • name属性では、要素の名前を設定します。

  • complexType要素は、定義する要素が、属性や子要素を持つ場合に設定します。

  • sequence要素は、定義する要素が親要素を持つ場合に設定します。

  • element要素は、要素を定義します。ここでは子要素carを定義しています。


    • ref属性は、他の要素への参照を設定します。ここでは、後述 name="car"を設定したelement要素を参照しています。

    • minOccur属性は、最小出現回数を設定します。1を設定すると、必須の要素となります。

    • maxOccur属性は、最大出現回数を設定します。unboundedを設定すると、何度でも記述できる要素となります。またunboundedとすると、生成された当要素のJavaインスタンスは、親要素のJavaインスタンスにおいてList型で保持されます。




1.3.element要素~その2~

複数の子要素と、属性を持つ場合は以下のように記述します。ここでは、car要素を定義しています。


cars.xsd

<!-- 略 -->

<element name="car">
<complexType>
<sequence>
<element ref="tns:maker" minOccurs="1" maxOccurs="1" />
<element ref="tns:model" minOccurs="1" maxOccurs="1" />
</sequence>
<attribute name="number" type="string"/>
</complexType>
</element>
<!-- 略 -->


  • attribute要素では、属性を定義します。


    • name属性では、属性名を定義します。

    • type属性では、型を定義します。




1.4.element要素~その3~

属性も子要素も持たない場合は以下のように記述します。


cars.xsd

<!-- 略 -->

<element name="maker" type="string" />
<element name="model" type="string" />
<!-- 略 -->


2.Javaクラスの生成(xjcコマンドの実行)

xjcコマンドを実行し、Javaクラスを生成します。macosのターミナルで実行しています。windowsでも同様にxjcコマンドで、Javaクラスを生成します。

$ xjc cars.xsd

以下のように、Javaクラスが生成されます。生成される場所は、xsdファイルのschema要素 targetNameSpace属性で設定したパスです。

$ xjc cars.xsd

スキーマの解析中...
スキーマのコンパイル中...
org/example/cars/Car.java
org/example/cars/Cars.java
org/example/cars/ObjectFactory.java
org/example/cars/package-info.java


3. xmlファイル作成 & xmlファイルからjavaインスタンス取得


3.1.xmlファイル作成

xmlファイルを作成します。以下のサンプルは上にも書きました。このxmlファイルから、JAXBを使用して、Javaインスタンスを取得します。


cars.xml

<?xml version="1.0" encoding="UTF-8"?>

<cars xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.example.org/cars"
xsi:schemalocation="http://www.example.org/cars cars.xsd">
<car number="0001">
<maker>HONDA</maker>
<model>civic</model>
</car>
<car number="0002">
<maker>LOTUS</maker>
<model>elise</model>
</car>
</cars>


  • ルート要素carsのxmlns属性に、xsdファイルのtargetNameSpace属性に設定した名前空間を設定します。

  • xsi:schemalocation属性には、名前空間とxsdファイルのパスをスペース区切りで記述します。


3.2.xmlファイルからJavaインスタンス取得

上のxmlファイルからCarsインスタンスを取得します。


Main.java

package test;

public class Main {
public static void main(String[] args) {
CarManager manager = new CarManager();
Cars cars = manager.getCars();
for (Car car : cars.car) {
System.out.println(car.getModel());
System.out.println(" number:[" + car.getNumber() + "]");
System.out.println(" maker:[" + car.getMaker() + "]");
}
}
}



CarManager.java

package test;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

public class CarManager {

public Cars getCars() {
File file = new File("/Users/ukiuki/Documents/workspace/JAXBTest/src/test/cars.xml");
try {
JAXBContext context = JAXBContext.newInstance(Cars.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
return (Cars) unmarshaller.unmarshal(file);

} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}


以下は、コンソールです。

civic

number:[0001]
maker:[HONDA]
elise
number:[0002]
maker:[LOTUS]


参考

参考にしました。ありがとうございます。

JAXBによるXMLデータとプログラムの双方向結合

以上です。ありがとうございました。