LoginSignup
29
33

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-09-23

先日、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データとプログラムの双方向結合

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

29
33
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
33