この章の内容は次のとおりです。
注意: 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エンコーディングを使用します。