この章の内容は次のとおりです。
|
注意: XMLデータのオブジェクト・バインディング機能を使用できるよう、新しいアプリケーションではJAXB Class Generatorを使用してください。Oracle9i Class Generator for Javaは非推奨です。Oracle Database 10gでは、下位互換性を保つためにOracle9iのClass Generatorがサポートされています。 |
この項では、Java Architecture for XML Binding(JAXB)の概要を示します。内容は次のとおりです。
この章では、次の内容を十分に理解していると想定します。
Java Architecture for XML Binding(JAXB): この章で説明する内容より詳しいJAXBの概要が必要な場合は、「はじめに」の「関連ドキュメント」にあるXMLの資料を参照してください。
XML Schema言語: 概要および関連資料へのリンクは、第7章「Schema Processor for Javaの使用」を参照してください。
Oracle JAXBプロセッサは、JCP(Java Community Process)の推奨によるJSR-31「The Java Architecture for XML Binding (JAXB)」バージョン1.0を実装しています。
JAXB 1.0仕様のOracle Database XDK実装では、次のオプション機能をサポートしていません。
Javadocの生成
フェイルファスト検証
外部カスタマイズ・ファイル
仕様のセクションE.2で説明されているXML Schemaの概念
JSRは、JCPのJava Specification Requestです。JSRの説明は、次のURLにあります。
http://jcp.org/en/jsr/overview
JAXB Class Generator for Javaでは、XML Schemaに対応するインタフェースおよび実装クラスを生成します。Java開発者にとっての主な利点は、XML文書とJavaコード間のマッピングの自動化です。この機能により、生成されたコードをプログラムで使用して、XMLデータの読取り、操作および再作成ができます。Javaクラスは拡張可能で、開発者は基礎となるXMLデータ構造に関する知識がなくてもXMLデータにアクセスできます。
つまり、Oracle JAXB Class Generatorを使用すると、JavaでのXMLアプリケーション開発に次の利点がもたらされます。
迅速性
スキーマからコードへの変換が自動化されるため、入力XMLスキーマからJavaコードを迅速に生成できます。
使いやすさ
自身でコードを最初から作成するかわりに、生成されたgetおよびsetメソッドをコールできます。
自動化されたデータ変換
Javaデータ型へのXML文書データの変換を自動化できます。
カスタマイズ
JAXBには、XMLの要素と属性のバインディングをカスタマイズできる柔軟なフレームワークが用意されています。
JAXBは、XMLデータをJavaオブジェクトにマップするAPIおよびツール・セットです。JAXBは、XML文書をJava形式のプログラムで表すことにより、JavaプログラムからXML文書へのアクセスを簡略化します。
JAXB APIおよびツールを使用して、次の基本タスクを実行できます。
orajaxbコマンドライン・ユーティリティを使用して、XMLスキーマからJAXBクラスを生成し、コンパイルします。
JAXB Class Generatorを使用してJavaクラスを生成するには、XMLスキーマを提供する必要があります。JAXBではDTDがサポートされません。ただし、「DTDからXMLスキーマへの変換」で説明しているように、DTD2Schemaプログラムを使用してDTDをXMLスキーマに変換できます。後でJAXB Class Generatorを使用して、スキーマからクラスを生成できます。
JAXBコンパイラは、ソースXMLスキーマの制約にマップされるJavaクラスを生成します。クラスで実装されるgetおよびsetメソッドを使用して、スキーマの各種要素および属性のデータを取得および指定できます。
生成されたクラスをJavaプログラムでインスタンス化することにより、XML文書を処理します。
具体的には、JAXBバインディング・フレームワークを使用するプログラムを作成して、次のタスクを実行できます。
XML文書をアンマーシャリングします。
JAXB仕様で説明されているように、アンマーシャリングとは、XML文書からJavaによって生成されたオブジェクトにデータを移動することと定義されています。
XML文書を検証します。
コンテンツをコンテンツ・ツリーにアンマーシャリングする前またはアンマーシャリング中に、検証を行うことができます。Javaオブジェクトに対して検証APIをコールすることにより、検証をオンデマンドで行うこともできます。「JAXBでの検証」を参照してください。
Javaコンテンツ・オブジェクトを変更します。
データ・オブジェクトのコンテンツ・ツリーは、ソースXML文書の構造とコンテンツを表します。クラスに対して定義されているsetメソッドを使用して、要素と属性のコンテンツを変更できます。
Javaコンテンツ・オブジェクトをXMLにマーシャリングします。
アンマーシャリングとは対照的に、マーシャリングとは、Javaクラスのインスタンスのコンテンツ・ツリーを全検索することによって、JavaオブジェクトからXML文書を作成することです。DOMツリー、SAXコンテンツ・ハンドラ、変換結果または出力ストリームをシリアライズできます。
Javaコンテンツ・ツリーは、ツリーのマーシャリングによって有効なXML文書が生成されるときに、XMLスキーマに関して有効であるとみなされます。
JAXBアプリケーションでは、次の状況で検証を実行できます。
アンマーシャリング時検証では、アンマーシャリング時のエラーおよび警告がアプリケーションに通知されます。アンマーシャリングに、エラーのない検証が含まれている場合、入力XML文書とJavaコンテンツ・ツリーは有効です。
オンデマンド検証は、アプリケーションによって開始された場合、Javaコンテンツ・ツリーに対して実行されます。
フェイルファスト検証は、setおよびgetメソッドを使用したJavaコンテンツ・ツリーの更新中に即時結果を戻します。「標準と仕様」で示されているように、フェイルファスト検証はJAXB 1.0仕様のオプション機能であり、JAXB Class GeneratorのXDK実装ではサポートされていません。
JAXBアプリケーションは、有効なJavaコンテンツ・ツリーをマーシャリングできる必要がありますが、マーシャリングAPIのいずれかをコールする前にJavaコンテンツ・ツリーが有効であることを確認する必要はありません。マーシャリング・プロセス自体は、コンテンツ・ツリーを検証しません。プログラムで行う必要があるのは、無効なコンテンツによりマーシャリングが失敗したときにjavax/xml/bind/MarshalExceptionをスローすることのみです。
XMLスキーマで宣言された要素と型名は、常に最も有用なJavaクラス名を提供するとはかぎりません。JAXB仕様で説明されているカスタム・バインディング宣言を使用して、デフォルトのJAXBバインディングをオーバーライドできます。これらの宣言により、XMLスキーマのXML固有の制約を超えて、生成されたJAXBクラスをカスタマイズして、クラス名とパッケージ名のマッピングなどのJava固有の改良点を含めることができます。
スキーマに注釈を加えて、次のカスタマイズを実行できます。
XML名をユーザー定義のJavaクラス名にバインドします。
パッケージ、導出クラスおよびメソッドに名前を付けます。
どの要素をどのクラスにバインドするかを選択します。
各属性および要素宣言を適切なコンテンツ・クラスのプロパティにバインドする方法を決定します。
各属性値のタイプまたはコンテンツ仕様を選択します。
表8-2に、JAXBのカスタマイズを示すデモ・プログラムをいくつか示します。
|
関連項目:
|
この項の内容は次のとおりです。
XDK JAXB APIでは、次のパッケージが公開されています。
javax.xml.bindは、アンマーシャリング、マーシャリングおよび検証を含むクライアント・アプリケーションのランタイム・バインディング・フレームワークを提供します。
javax.xml.bind.utilは、役に立つクライアント・ユーティリティ・クラスを提供します。
表8-1に、javax.xml.bindパッケージの最も重要なクラスおよびインタフェースを示します。これらのクラスおよびインタフェースは、ほとんどのJAXBアプリケーションのコアを形成します。
表8-1 javax.xml.bindのクラスおよびインタフェース
| クラス/インタフェース | 説明 | メソッド |
|---|---|---|
|
|
JAXBバインディング・フレームワーク操作(アンマーシャリング、マーシャリングおよび検証)の実装に必要なXML/Javaバインディング情報の管理の抽象化を提供します。クライアント・アプリケーションは、 |
主要なメソッドは次のとおりです。
|
|
|
Javaコンテンツ・ツリーのXMLデータへのシリアライズのプロセスを管理します。 |
主要なメソッドは次のとおりです。
|
|
|
XMLデータを新規に作成されたJavaコンテンツ・ツリーにデシリアライズし、オプションとしてXMLデータのアンマーシャリング時に検証を行うプロセスを管理します。 |
主要なメソッドは次のとおりです。
|
|
|
実行時のコンテンツ・ツリーの検証を制御します。具体的には、このインタフェースはオンデマンド検証を制御します。オンデマンド検証により、クライアントは、Javaコンテンツ・ツリーで検出された検証エラーおよび警告に関するデータを受け取ることができます。 |
主要なメソッドは次のとおりです。
|
図8-1に、JAXB Class Generatorを使用するフレームワークのプロセス・フローを示します。
図8-1に示したプロセスの基本ステージは次のとおりです。
XMLパーサーは、XMスキーマを解析し、解析したデータをJAXB Class Generatorに送信します。
Class Generatorは、入力XMLスキーマに基づいてJavaクラスおよびインタフェースを作成します。
デフォルトでは、1つのXML要素または型宣言により1つのインタフェースと1つのクラスが生成されます。たとえば、スキーマが<anElement>という名前の要素を定義する場合、デフォルトでは、JAXB Class GeneratorはAnElement.javaという名前のソース・ファイルとAnElementImpl.javaという名前の別のファイルを生成します。カスタマイズ・バインディング宣言を使用して、XML SchemaコンポーネントからJava表現へのデフォルト・バインディングをオーバーライドできます。
Javaコンパイラは、.javaソース・ファイルをクラス・ファイルにコンパイルします。生成されたクラス、ソース・ファイルおよびアプリケーション・コードはすべてコンパイルする必要があります。
Javaアプリケーションでは、コンパイルされたクラスとバインディング・フレームワークを使用して、次のタイプのタスクを実行します。
JAXBコンテキストを作成する。このコンテキストを使用して、MarshallerとUnmarshallerを作成します。
XMLスキーマに対して有効なXMLデータを表すオブジェクト・ツリーを構築する。このタスクは、スキーマに準拠するXML文書からデータをアンマーシャリングするか、クラスをインスタンス化することにより実行できます。
データにアクセスし変更する。
オプションで、XML Schemaで表現された制約と比較し、データへの変更を検証する。
データを新規XML文書にマーシャリングする。
|
関連項目:
|
JAXB Class Generator for Javaのデモ・プログラムは、$ORACLE_HOME/xdk/demo/java/jaxbにあります。表8-2に、XDKに含まれるJAXBのデモを具体的に示します。
表8-2 JAXB Class Generatorのデモ
| プログラム | Oracleホーム内のサブディレクトリ | デモの内容 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
別の最上位レベルの |
|
|
|
最上位レベルの名前付きグループを参照する |
|
|
|
|
|
|
|
アトミック・データ型のバインディング。 |
|
|
|
|
|
|
|
2つの異なる名前空間で宣言されている要素と型のバインディング。 |
|
|
|
Javaパッケージ名のカスタマイズ。 |
|
|
|
最上位レベル要素のクラス名のカスタマイズ。このプログラムの詳細な説明は、「最上位レベル要素でのクラス名のカスタマイズ」を参照してください。 |
|
|
|
|
|
|
|
属性名のカスタマイズ。 |
|
|
|
グローバル |
|
|
|
TypeSafe Enumクラス名のカスタマイズ。 |
サンプル・プログラムのコンパイルおよび実行方法を説明するドキュメントは、同じディレクトリ内のREADMEにあります。基本手順は次のとおりです。
ディレクトリを$ORACLE_HOME/xdk/demo/java/jaxbディレクトリ(UNIXの場合)または%ORACLE_HOME%\xdk\demo\java\jaxbディレクトリ(Windowsの場合)に変更します。
「Java XDK環境の設定」の説明に従って、環境変数が設定されていることを確認します。
システム・プロンプトでmake(UNIXの場合)またはMake.bat(Windowsの場合)を実行します。makeユーティリティは、各サンプル・サブディレクトリに対して次の順次アクションを実行します。
orajaxbユーティリティを実行して、入力XMLスキーマに基づくJavaクラス・ファイルを生成します。ほとんどのデモでは、出力クラス・ファイルはgeneratedサブディレクトリに書き込まれます。たとえば、makeファイルはSample1サブディレクトリ内のsample1.xsdスキーマに対して次のコマンドを実行します。
cd ./Sample1; $(JAVA_HOME)/bin/java -classpath "$(MAKE_CLASSPATH)" \ oracle.xml.jaxb.orajaxb -schema sample1.xsd -targetPkg generated; echo;
javacユーティリティを実行してJavaクラスをコンパイルします。たとえば、makeユーティリティはSample1/generated/サブディレクトリ内のJavaクラス・ファイルに対して次のコマンドを実行します。
cd ./Sample1/generated; $(JAVA_HOME)/bin/javac -classpath \ "$(MAKE_CLASSPATH)" *.java
javacユーティリティを実行して、前の手順でコンパイルされたクラスを使用するサンプルJavaアプリケーションをコンパイルします。たとえば、makeユーティリティはSampleApp1.javaプログラムをコンパイルします。
cd ./Sample1; $(JAVA_HOME)/bin/javac -classpath "$(MAKE_CLASSPATH)" \ SampleApp1.java
サンプルJavaアプリケーションを実行し、結果をログ・ファイルに書き込みます。たとえば、makeユーティリティはSampleApp1クラスを実行し、出力をsample1.outに書き込みます。
cd ./Sample1; $(JAVA_HOME)/bin/java -classpath "$(MAKE_CLASSPATH)" \SampleApp1 > sample1.out
XDKには、入力XMLスキーマからJavaクラスを生成するコマンドラインJavaインタフェースであるorajaxbが含まれています。$ORACLE_HOME/bin/orajaxbおよび%ORACLE_HOME%\bin\orajaxb.batシェル・スクリプトは、oracle.xml.jaxb.orajaxbクラスを実行します。orajaxbを使用するには、CLASSPATHが「Java XDK環境の設定」の説明に従って設定されていることを確認します。
表8-3に、orajaxbのコマンドライン・オプションを示します。
表8-3 orajaxbのコマンドライン・オプション
| オプション | 用途 |
|---|---|
|
- |
ヘルプ・メッセージを出力します。 |
|
- |
バージョン番号を出力します。 |
|
- |
Javaソース・ファイルの生成先ディレクトリを指定します。スキーマに名前空間がある場合、プログラムでは、outputDirから参照されるパッケージ(名前空間に対応)にJavaコードが生成されます。デフォルトでは、現行ディレクトリは |
|
- |
入力XMLスキーマを指定します。 |
|
- |
ターゲット・パッケージ名を指定します。このオプションは、パッケージ名のバインディング・カスタマイズと、JAXB仕様で定義されているデフォルトのパッケージ名アルゴリズムをオーバーライドします。 |
|
- |
インタフェースのみを生成します。 |
|
- |
生成されたクラスおよびインタフェースをリストします。 |
|
- |
デフォルトのカスタマイズ・ファイルを生成します。 |
|
- |
ベンダー固有の拡張を許可し、JAXB 1.0仕様の付録E.2に指定されている互換性ルールに厳密には従いません。これが指定されている場合、プログラムでは、表記法、置換グループ、属性など、JAXB 1.0でサポートされていない機能は無視されます。 |
orjaxbをテストするには、$ORACLE_HOME/xdk/demo/java/jaxb/Sample1ディレクトリに変更します。makeを実行した場合、ディレクトリには次のファイルが含まれています。
SampleApp1.class SampleApp1.java generated/ sample1.out sample1.xml sample1.xsd
sample.xsdファイルは、sample1.xmlに関連付けられているXMLスキーマです。generated/サブディレクトリには、入力スキーマから生成されたクラスが含まれます。次のように、generated/のコンテンツを削除し、クラスを再生成することにより、orajaxbをテストできます。
rm generated/* orajaxb -schema sample1.xsd -targetPkg generated -verbose
端末には次の出力が表示されます。
generated/CType.java generated/AComplexType.java generated/AnElement.java generated/RElemOfCTypeInSameNs.java generated/RType.java generated/RElemOfSTypeInSameNs.java generated/CTypeImpl.java generated/AComplexTypeImpl.java generated/AnElementImpl.java generated/RElemOfCTypeInSameNsImpl.java generated/RTypeImpl.java generated/RElemOfSTypeInSameNsImpl.java generated/ObjectFactory.java
この項の内容は次のとおりです。
Sample3.javaプログラムは、複合型定義をJavaコンテンツ・インタフェースにバインドする方法を示します。XMLスキーマで定義されている1つの複合型は、別の複合型からの拡張によって導出されます。
例8-1に、サンプル・アプリケーションへの入力を提供するXMLデータ文書を示します。sample3.xml文書では、従業員の住所を記述します。
例8-1 sample3.xml
<?xml version="1.0"?>
<myAddress xmlns = "http://www.oracle.com/sample3/"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://www.oracle.com/sample3 sample3.xsd">
<name>James Bond</name>
<doorNumber>420</doorNumber>
<street>Oracle parkway</street>
<city>Redwood shores</city>
<state>CA</state>
<zip>94065</zip>
<country>United States</country>
</myAddress>
例8-2に示すXMLスキーマは、sample3.xmlの検証に使用する構造を定義します。スキーマでは、次のように定義されている2つの複合型と1つの要素を定義します。
Addressという名前の最初の複合型は要素のシーケンスです。シーケンスで定義されている各要素は、住所の一部(名前、ドア番号など)を表します。
USAddressという名前の2番目の複合型は、<extension base="exp:Address">要素を使用して、Addressシーケンスに州や郵便番号などの米国固有の要素を追加することによりAddressを拡張します。接頭辞expは、http://www.oracle.com/sample3/名前空間を指定します。
要素はmyAddressという名前で、その型はexp:USAddressです。接頭辞expは、http://www.oracle.com/sample3/名前空間を指定します。sample3.xmlでは、最上位レベル要素myAddressは名前空間http://www.oracle.com/sample3/にあり、スキーマ定義に準拠します。
例8-2 sample3.xsd
<?xml version="1.0"?>
<!-- Binding a complex type definition to java content interface
The complex type definition is derived by extension
-->
<schema xmlns = "http://www.w3.org/2001/XMLSchema"
xmlns:exp="http://www.oracle.com/sample3/"
targetNamespace="http://www.oracle.com/sample3/"
elementFormDefault="qualified">
<complexType name="Address">
<sequence>
<element name="name" type="string"/>
<element name="doorNumber" type="short"/>
<element name="street" type="string"/>
<element name="city" type="string"/>
</sequence>
</complexType>
<complexType name="USAddress">
<complexContent>
<extension base="exp:Address">
<sequence>
<element name="state" type="string"/>
<element name="zip" type="integer"/>
<element name="country" type="string"/>
</sequence>
</extension>
</complexContent>
</complexType>
<element name="myAddress" type="exp:USAddress"/>
</schema>
XML文書および対応するXMLスキーマがある場合、処理の次のステージは、XMLスキーマからJavaクラスを生成することです。「JAXB Class Generatorコマンドライン・ユーティリティの使用」で説明したJAXBコマンドライン・インタフェースを使用して、このタスクを実行できます。
「Java XDK環境の設定」の説明に従って環境が設定されていると想定した場合は、次のようにgeneratedパッケージにソース・ファイルを作成できます。
cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample3 orajaxb -schema sample1.xsd -targetPkg generated
前のorajaxbコマンドでは、./generated/サブディレクトリに次のソース・ファイルを作成する必要があります。
Address.java AddressImpl.java MyAddress.java MyAddressImpl.java ObjectFactory.java USAddress.java USAddressImpl.java
要素MyAddressと同様に、複合型AddressおよびUSAddressには、それぞれ2つのソース・ファイルが関連付けられています。要素に基づいて名前が付けられたソース・ファイルには、インタフェースが含まれます。接尾辞がImplのファイルには、インタフェースを実装するクラスが含まれます。たとえば、Address.javaにはインタフェースAddressが含まれますが、AddressImpl.javaにはAddressを実装するクラスが含まれます。
Address.javaソース・ファイルのコンテンツを例8-3に示します。
例8-3 Address.java
package generated;
public interface Address
{
public void setName(java.lang.String n);
public java.lang.String getName();
public void setDoorNumber(short d);
public short getDoorNumber();
public void setStreet(java.lang.String s);
public java.lang.String getStreet();
public void setCity(java.lang.String c);
public java.lang.String getCity();
}
Address複合型では、要素のシーケンス(name、doorNumber、streetおよびcity)を定義しました。したがって、Addressインタフェースには、4つの各要素に対するgetおよびsetメソッド署名が含まれます。たとえば、インタフェースには、<name>要素内のデータを取得するためのgetName()およびこの要素内のデータを変更するためのsetName()が含まれます。
Javaソース・ファイルはjavacを使用して次のようにコンパイルできます。
cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample3/generated javac *.java
Sample3.javaは、「Javaクラスの生成およびコンパイル」で生成したJavaクラス・ファイルを使用してsample3.xml文書を処理する方法を示します。サンプル・プログラムは、XMLデータ文書をアンマーシャリングしてマーシャリングし、生成されたクラスを使用して住所データを出力および変更します。
Sample3.javaプログラムでは、データを次のように処理します。
XMLデータ文書のファイル名、および生成されたクラスを含むディレクトリの名前の文字列を作成します。この名前はパッケージ名です。次に例を示します。
String fileName = "sample3.xml"; String instancePath = "generated";
JAXBContext.newInstance()を起動することにより、JAXBコンテンツをインスタンス化します。クライアント・アプリケーションは、コンテキスト・パスで初期化することにより、このクラスの新規インスタンスを取得します。パスには、Marshallerで使用可能なインタフェースを含むJavaパッケージ名のリストが含まれます。この方法を示す文は次のとおりです。
JAXBContext jc = JAXBContext.newInstance(instancePath);
Unmarshallerをインスタンス化します。Unmarshallerクラスは、XMLデータを新規に作成されたオブジェクトにデシリアライズし、オプションとしてXMLデータのアンマーシャリング時に検証を行うプロセスを管理します。この方法を示す文は次のとおりです。
Unmarshaller u = jc.createUnmarshaller();
XML文書をアンマーシャリングします。Unmarshaller.unmarshal()メソッドを起動して、sample3.xml文書をデシリアライズし、コンテンツ・ツリーをObjectとして戻します。fileToUrl()ヘルパー・メソッドを起動することにより、XMLファイル名からURLを作成できます。この方法を示す文は次のとおりです。
Object obj = u.unmarshal(fileToURL(fileName));
Marshallerをインスタンス化します。Marshallerクラスは、Javaコンテンツ・ツリーのXMLデータへのシリアライズのプロセスを管理します。この方法を示す文は次のとおりです。
Marshaller m = jc.createMarshaller();
コンテンツ・ツリーをマーシャリングします。Marshaller.marshal()メソッドを起動して、Unmarshallerから戻されたコンテンツ・ツリーObjectをマーシャリングします。DOMツリー、SAXコンテンツ・ハンドラ、変換結果または出力ストリームをシリアライズできます。次の文は、マークアップを含めたXMLデータを出力ストリームとしてシリアライズします。
m.marshal(obj, System.out);
デフォルトでは、Marshallerは出力ストリームにXMLデータを書き込むときにUTF-8エンコーディングを使用します。
XML文書のコンテンツを出力します。プログラムでは、コンテンツ・ツリーとMarshallerをパラメータとして受け入れるprocess()メソッドを実装します。
処理の最初のステージでは、XMLマークアップのないXML文書内のデータを出力します。メソッドは、Marshallerにより生成されたObjectをMyAddress型にキャストします。このメソッドは、XML要素の名前の先頭にgetを付けることでメソッド名が作成された一連のメソッドを起動します。たとえば、例8-1の<city>要素内のデータを取得するために、プログラムはgetCity()を起動します。次のコード部分は、この方法を示します。
public static void process(Object obj, Marshaller m) throws Throwable
{
generated.MyAddress elem = (generated.MyAddress)obj;
System.out.println();
System.out.println(" My address is: ");
System.out.println(" name: " + elem.getName() + "\n" +
" doorNumber " + elem.getDoorNumber() + "\n" +
" street: " + elem.getStreet() + "\n" +
" city: " + elem.getCity() + "\n" +
" state: " + elem.getState() + "\n" +
" zip: " + elem.getZip() + "\n" +
" country: " + elem.getCountry() + "\n" +
"\n" );
...
XMLデータを変更し、出力します。process()メソッドは、先行するgetメソッドに対応するsetメソッドを起動することで続行します。各setメソッドの名前は、XML要素名の先頭にsetを付けることで作成されます。たとえば、setCountry()は<country>要素内の値を変更します。次の文は、この方法を示します。
short num = 550;
elem.setDoorNumber(num);
elem.setCountry("India");
num = 10100;
elem.setZip(new java.math.BigInteger("100100"));
elem.setCity("Noida");
elem.setState("Delhi");
データを変更した後、プログラムは、前の手順と同じgetメソッドを起動することによりデータを出力します。
Sample10.javaプログラムは、JAXBカスタマイズの1つの形式を示します。プログラムでは、入力XMLスキーマの要素に対応するクラスの名前を変更できることを示します。
例8-4に、サンプル・アプリケーションへの入力を提供するXMLデータ文書を示します。sample10.xml文書は業務を記述します。
例8-4 sample10.xml
<?xml version="1.0"?> <business xmlns="http://jaxbcustomized/sample10/"> <title>Software Development</title> <owner>Larry Peterson</owner> <id>45123</id> </business>
例8-5に、sample10.xmlの構造を定義するXMLスキーマを示します。スキーマでは、次のように1つの複合型と1つの要素を定義します。
businessTypeという名前の複合型は要素のシーケンスです。シーケンスで定義されている各要素は、業務の一部(タイトル、所有者およびID)を表します。
businessという名前の要素の型はbiz:businessTypeです。biz接頭辞は、http://jaxbcustomized/sample10/名前空間を指定します。sample10.xmlでは、最上位レベル要素businessは名前空間http://jaxbcustomized/sample10/にあり、スキーマ定義に準拠します。
例8-5 sample10.xsd
<?xml version="1.0"?>
<!-- Customization of class name in top level element -->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://jaxbcustomized/sample10/"
xmlns:biz="http://jaxbcustomized/sample10/"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="1.0"
elementFormDefault="qualified">
<element name="business" type="biz:businessType">
<annotation>
<appinfo>
<jaxb:class name="myBusiness"/>
</appinfo>
</annotation>
</element>
<complexType name="businessType">
<sequence>
<element name="title" type="string"/>
<element name="owner" type="string"/>
<element name="id" type="integer"/>
</sequence>
</complexType>
</schema>
例8-5に示したスキーマは、インライン・バインディング宣言を使用して、business要素のバインディングをカスタマイズします。インライン・カスタマイズの一般的な形式は次のとおりです。
<xs:annotation>
<xs:appinfo>
.
.
binding declarations
.
.
</xs:appinfo>
</xs:annotation>
例8-5では、<class>バインディング宣言を使用してスキーマ要素をJavaクラス名にバインドしています。宣言を使用して、インタフェースの名前またはインタフェースを実装するクラスをカスタマイズできます。JAXB Class Generatorでは、<class>カスタマイズに対して次の構文をサポートしています。
<class [ name = "className"] >
name属性では、導出されたJavaインタフェースの名前を指定します。例8-5には、次のカスタマイズが含まれます。
<jaxb:class name="myBusiness"/>
このため、スキーマはbusiness要素をデフォルトのインタフェースbusinessではなくインタフェースmyBusinessにバインドします。
XML文書および対応するXMLスキーマがある場合、次のステージは、XMLスキーマからJavaクラスを生成することです。JAXBコマンドライン・インタフェースを使用して、このタスクを実行できます。
「Java XDK環境の設定」の説明に従って環境が設定されている場合は、次のようにgeneratedパッケージにソース・ファイルを作成できます。
cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample10 orajaxb -schema sample10.xsd
前述のコマンドはターゲット・パッケージを指定しないため、パッケージ名はスキーマのターゲット名前空間(http://jaxbcustomized/sample10/)から作成されます。したがって、ユーティリティでは、./jaxbcustomized/sample10/サブディレクトリに次のソース・ファイルが生成されます。
BusinessType.java BusinessTypeImpl.java MyBusiness.java MyBusinessImpl.java ObjectFactory.java
複合型businessTypeにはBusinessType.javaおよびBusinessTypeImpl.javaという2つのソース・ファイルがあることに注意してください。JAXBのカスタマイズにより、business要素はインタフェースMyBusinessにバインドされ、クラスMyBusinessImplを実装しています。
BusinessType.javaソース・ファイルのコンテンツを例8-6に示します。
例8-6 BusinessType.java
package jaxbcustomized.sample10;
public interface BusinessType
{
public void setTitle(java.lang.String t);
public java.lang.String getTitle();
public void setOwner(java.lang.String o);
public java.lang.String getOwner();
public void setId(java.math.BigInteger i);
public java.math.BigInteger getId();
}
BusinessType複合型では、要素のシーケンス(title、ownerおよびid)を定義しました。したがって、Addressインタフェースには、各要素に対するgetおよびsetメソッド署名が含まれます。たとえば、インタフェースには、<title>要素内のデータを取得するためのgetTitle()およびこの要素内のデータを変更するためのsetTitle()が含まれます。
Javaソース・ファイルはjavacを使用して次のようにコンパイルできます。
cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample10/jaxbcustomized/sample10 javac *.java
Sample10.javaソース・ファイルは、「Javaクラスの生成およびコンパイル」で生成したクラス・ファイルを使用してsample10.xml文書のデータを処理する方法を示しています。サンプル・プログラムは、XML文書をアンマーシャリングし、そのコンテンツを出力し、XMLを標準出力にマーシャリングします。
Sample10.javaプログラムでは、XMLデータを次のように処理します。
XMLデータ文書のファイル名、および生成されたクラスを含むディレクトリの名前の文字列を作成します。この名前はパッケージ名です。次に例を示します。
String fileName = "sample10.xml"; String instancePath = "jaxbcustomized.sample10";
JAXBContext.newInstance()メソッドを起動することにより、JAXBコンテンツをインスタンス化します。この方法を示す文は次のとおりです。
JAXBContext jc = JAXBContext.newInstance(instancePath);
Unmarshallerを作成します。この方法を示す文は次のとおりです。
Unmarshaller u = jc.createUnmarshaller();
XML文書をアンマーシャリングします。プログラムは、文書を2回アンマーシャリングします。最初にObjectを戻し、次にキャストを使用してMyBusinessオブジェクトを戻します。この方法を示す文は次のとおりです。
Object obj = u.unmarshal(fileToURL(fileName));
jaxbcustomized.sample10.MyBusiness bus =
(jaxbcustomized.sample10.MyBusiness) u.unmarshal(fileToURL(fileName));
XML文書のコンテンツを出力します。プログラムは、MyBusinessオブジェクトに対してgetメソッドを起動します。次のコード部分は、この方法を示します。
System.out.println("My business details are: ");
System.out.println(" title: " + bus.getTitle());
System.out.println(" owner: " + bus.getOwner());
System.out.println(" id: " + bus.getId().toString());
System.out.println();
Marshallerを作成します。この方法を示す文は次のとおりです。
Marshaller m = jc.createMarshaller();
Marshallerを構成します。setProperty()を起動して、Marshallerの様々なプロパティを構成できます。JAXB_FORMATTED_OUTPUT定数は、MarshallerがXMLデータを改行とインデントで書式設定する必要があることを指定します。次の文は、この方法を示します。
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
コンテンツ・ツリーをマーシャリングします。次の文は、マークアップを含めたXMLデータを出力ストリームとしてシリアライズします。
m.marshal(bus, System.out);
デフォルトでは、Marshallerは出力ストリームにXMLデータを書き込むときにUTF-8エンコーディングを使用します。