ヘッダーをスキップ
Oracle XML Developer's Kitプログラマーズ・ガイド
11gリリース1(11.1)
E05676-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

8 JAXB Class Generatorの使用

この章の内容は次のとおりです。


注意:

XMLデータのオブジェクト・バインディング機能を使用できるよう、新しいアプリケーションではJAXB Class Generatorを使用してください。Oracle9i Class Generator for Javaは非推奨です。Oracle Database 10gでは、下位互換性を保つためにOracle9iのClass Generatorがサポートされています。

JAXB Class Generatorの概要

この項では、Java Architecture for XML Binding(JAXB)の概要を示します。内容は次のとおりです。

前提条件

この章では、次の内容を十分に理解していると想定します。

標準と仕様

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

関連項目:

XDKがサポートする標準の概要は、第31章「XDK標準」を参照してください。

JAXB Class Generatorの機能

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を使用したマーシャリングおよびアンマーシャリング

JAXBは、XMLデータをJavaオブジェクトにマップするAPIおよびツール・セットです。JAXBは、XML文書をJava形式のプログラムで表すことにより、JavaプログラムからXML文書へのアクセスを簡略化します。

JAXB APIおよびツールを使用して、次の基本タスクを実行できます。

  1. orajaxbコマンドライン・ユーティリティを使用して、XMLスキーマからJAXBクラスを生成し、コンパイルします。

    JAXB Class Generatorを使用してJavaクラスを生成するには、XMLスキーマを提供する必要があります。JAXBではDTDがサポートされません。ただし、「DTDからXMLスキーマへの変換」で説明しているように、DTD2Schemaプログラムを使用してDTDをXMLスキーマに変換できます。後でJAXB Class Generatorを使用して、スキーマからクラスを生成できます。

    JAXBコンパイラは、ソースXMLスキーマの制約にマップされるJavaクラスを生成します。クラスで実装されるgetおよびsetメソッドを使用して、スキーマの各種要素および属性のデータを取得および指定できます。

  2. 生成されたクラスをJavaプログラムでインスタンス化することにより、XML文書を処理します。

    具体的には、JAXBバインディング・フレームワークを使用するプログラムを作成して、次のタスクを実行できます。

    1. XML文書をアンマーシャリングします。

      JAXB仕様で説明されているように、アンマーシャリングとは、XML文書からJavaによって生成されたオブジェクトにデータを移動することと定義されています。

    2. XML文書を検証します。

      コンテンツをコンテンツ・ツリーにアンマーシャリングする前またはアンマーシャリング中に、検証を行うことができます。Javaオブジェクトに対して検証APIをコールすることにより、検証をオンデマンドで行うこともできます。「JAXBでの検証」を参照してください。

    3. Javaコンテンツ・オブジェクトを変更します。

      データ・オブジェクトのコンテンツ・ツリーは、ソースXML文書の構造とコンテンツを表します。クラスに対して定義されているsetメソッドを使用して、要素と属性のコンテンツを変更できます。

    4. Javaコンテンツ・オブジェクトをXMLにマーシャリングします。

      アンマーシャリングとは対照的に、マーシャリングとは、Javaクラスのインスタンスのコンテンツ・ツリーを全検索することによって、JavaオブジェクトからXML文書を作成することです。DOMツリー、SAXコンテンツ・ハンドラ、変換結果または出力ストリームをシリアライズできます。

JAXBでの検証

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をスローすることのみです。

JAXBのカスタマイズ

XMLスキーマで宣言された要素と型名は、常に最も有用なJavaクラス名を提供するとはかぎりません。JAXB仕様で説明されているカスタム・バインディング宣言を使用して、デフォルトのJAXBバインディングをオーバーライドできます。これらの宣言により、XMLスキーマのXML固有の制約を超えて、生成されたJAXBクラスをカスタマイズして、クラス名とパッケージ名のマッピングなどのJava固有の改良点を含めることができます。

スキーマに注釈を加えて、次のカスタマイズを実行できます。

  • XML名をユーザー定義のJavaクラス名にバインドします。

  • パッケージ、導出クラスおよびメソッドに名前を付けます。

  • どの要素をどのクラスにバインドするかを選択します。

  • 各属性および要素宣言を適切なコンテンツ・クラスのプロパティにバインドする方法を決定します。

  • 各属性値のタイプまたはコンテンツ仕様を選択します。

表8-2に、JAXBのカスタマイズを示すデモ・プログラムをいくつか示します。


関連項目:


JAXB Class Generatorの使用: 概要

この項の内容は次のとおりです。

JAXBプロセッサの使用: 基本プロセス

XDK JAXB APIでは、次のパッケージが公開されています。

  • javax.xml.bindは、アンマーシャリング、マーシャリングおよび検証を含むクライアント・アプリケーションのランタイム・バインディング・フレームワークを提供します。

  • javax.xml.bind.utilは、役に立つクライアント・ユーティリティ・クラスを提供します。

表8-1に、javax.xml.bindパッケージの最も重要なクラスおよびインタフェースを示します。これらのクラスおよびインタフェースは、ほとんどのJAXBアプリケーションのコアを形成します。

表8-1 javax.xml.bindのクラスおよびインタフェース

クラス/インタフェース 説明 メソッド

JAXBContextクラス

JAXBバインディング・フレームワーク操作(アンマーシャリング、マーシャリングおよび検証)の実装に必要なXML/Javaバインディング情報の管理の抽象化を提供します。クライアント・アプリケーションは、newInstance()メソッドを起動することにより、このクラスの新規インスタンスを取得します。

主要なメソッドは次のとおりです。

  • newInstance()はJAXBコンテンツ・クラスを作成します。このメソッドには、生成されたクラスを含むパッケージの名前を提供します。

  • createMarshaller()は、コンテンツ・ツリーからXMLへの変換に使用できるMarshallerを作成します。

  • createUnmarshaller()は、XMLからコンテンツ・ツリーへの変換に使用できるUnmarshallerを作成します。

  • createValidator()は、Javaコンテンツ・ツリーがそのソース・スキーマに対して妥当かどうかを検証できるValidatorオブジェクトを作成します。

Marshallerインタフェース

Javaコンテンツ・ツリーのXMLデータへのシリアライズのプロセスを管理します。

主要なメソッドは次のとおりです。

  • getEventHandler()は、現在のイベント・ハンドラまたはデフォルトのイベント・ハンドラを戻します。

  • getProperty()は、Marshallerの基礎となる実装のプロパティを取得します。

  • marshal()は、コンテンツ・ツリーをDOM、SAX2イベント、出力ストリーム、変換結果またはWriterにマーシャリングします。

  • setEventHandler()は、Javaコンテンツ・ツリーがそのソース・スキーマに対して妥当かどうかを検証するValidatorオブジェクトを作成します。

Unmarshallerインタフェース

XMLデータを新規に作成されたJavaコンテンツ・ツリーにデシリアライズし、オプションとしてXMLデータのアンマーシャリング時に検証を行うプロセスを管理します。

主要なメソッドは次のとおりです。

  • getEventHandler()は、現在のイベント・ハンドラまたはデフォルトのイベント・ハンドラを戻します。

  • getUnmarshallerHandler()は、XMLパイプラインのコンポーネントとして役立つUnmarshallerハンドラ・オブジェクトを戻します。

  • isValidating()は、Unmarshallerが検証モードに設定されているかどうかを示します。

  • setEventHandler()は、アプリケーションがValidationEventHandlerを登録できるようにします。

  • setValidating()は、Unmarshallerがアンマーシャリング操作時に検証を行う必要があるかどうかを指定します。

  • marshal()は、指定されたファイル、URL、入力ストリーム、入力ソース、SAXまたはDOMからXMLデータをアンマーシャリングします。

Validatorインタフェース

実行時のコンテンツ・ツリーの検証を制御します。具体的には、このインタフェースはオンデマンド検証を制御します。オンデマンド検証により、クライアントは、Javaコンテンツ・ツリーで検出された検証エラーおよび警告に関するデータを受け取ることができます。

主要なメソッドは次のとおりです。

  • getEventHandler()は、現在のイベント・ハンドラまたはデフォルトのイベント・ハンドラを戻します。

  • setEventHandler()は、アプリケーションがValidationEventHandlerを登録できるようにします。

  • validate()は、実行時にJavaコンテンツ・ツリーをオンデマンドで検証します。このメソッドは、Javaコンテンツ・ツリーの任意のサブツリーを検証できます。

  • validateRoot()は、rootObjをルートとするJavaコンテンツ・ツリーを検証します。このメソッドを使用して、Javaコンテンツ・ツリー全体を検証できます。


図8-1に、JAXB Class Generatorを使用するフレームワークのプロセス・フローを示します。

図8-1 JAXB Class Generator for Java

この図については次のテキストで説明しています。
「図8-1 JAXB Class Generator for Java」の説明

図8-1に示したプロセスの基本ステージは次のとおりです。

  1. XMLパーサーは、XMスキーマを解析し、解析したデータをJAXB Class Generatorに送信します。

  2. Class Generatorは、入力XMLスキーマに基づいてJavaクラスおよびインタフェースを作成します。

    デフォルトでは、1つのXML要素または型宣言により1つのインタフェースと1つのクラスが生成されます。たとえば、スキーマが<anElement>という名前の要素を定義する場合、デフォルトでは、JAXB Class GeneratorはAnElement.javaという名前のソース・ファイルとAnElementImpl.javaという名前の別のファイルを生成します。カスタマイズ・バインディング宣言を使用して、XML SchemaコンポーネントからJava表現へのデフォルト・バインディングをオーバーライドできます。

  3. Javaコンパイラは、.javaソース・ファイルをクラス・ファイルにコンパイルします。生成されたクラス、ソース・ファイルおよびアプリケーション・コードはすべてコンパイルする必要があります。

  4. Javaアプリケーションでは、コンパイルされたクラスとバインディング・フレームワークを使用して、次のタイプのタスクを実行します。

    • JAXBコンテキストを作成する。このコンテキストを使用して、MarshallerとUnmarshallerを作成します。

    • XMLスキーマに対して有効なXMLデータを表すオブジェクト・ツリーを構築する。このタスクは、スキーマに準拠するXML文書からデータをアンマーシャリングするか、クラスをインスタンス化することにより実行できます。

    • データにアクセスし変更する。

    • オプションで、XML Schemaで表現された制約と比較し、データへの変更を検証する。

    • データを新規XML文書にマーシャリングする。


関連項目:


XML Schema Processorのデモ・プログラムの実行

JAXB Class Generator for Javaのデモ・プログラムは、$ORACLE_HOME/xdk/demo/java/jaxbにあります。表8-2に、XDKに含まれるJAXBのデモを具体的に示します。

表8-2 JAXB Class Generatorのデモ

プログラム Oracleホーム内のサブディレクトリ デモの内容

SampleApp1.java

/xdk/demo/java/jaxb/Sample1

sample1.xsdスキーマ内の最上位レベルの要素とcomplexType定義のJavaクラスへのバインディング。

SampleApp2.java

/xdk/demo/java/jaxb/Sample2

sample2.xsdスキーマ内の最上位レベルの要素とインラインsimpleType定義のバインディング。

SampleApp3.java

/xdk/demo/java/jaxb/Sample3

別の最上位レベルのcomplexType定義からの拡張により導出された最上位レベルのcomplexType要素のバインディング。このプログラムの詳細な説明は、「複合型のバインディング」を参照してください。

SampleApp4.java

/xdk/demo/java/jaxb/Sample4

最上位レベルの名前付きグループを参照するcomplexType内のコンテンツ・モデルのバインディング。

SampleApp5.java

/xdk/demo/java/jaxb/Sample5

complexType内でアンバインドされたmaxOccurs<choice>とのバインディング。

SampleApp6.java

/xdk/demo/java/jaxb/Sample6

アトミック・データ型のバインディング。

SampleApp7.java

/xdk/demo/java/jaxb/Sample7

mixed="true"complexType定義のバインディング。

SampleApp8.java

/xdk/demo/java/jaxb/Sample8

2つの異なる名前空間で宣言されている要素と型のバインディング。

SampleApp9.java

/xdk/demo/java/jaxb/Sample9

Javaパッケージ名のカスタマイズ。

SampleApp10.java

/xdk/demo/java/jaxb/Sample10

最上位レベル要素のクラス名のカスタマイズ。このプログラムの詳細な説明は、「最上位レベル要素でのクラス名のカスタマイズ」を参照してください。

SampleApp11.java

/xdk/demo/java/jaxb/Sample11

complexType要素の内部で宣言されたモデル・グループの反復で発生するローカル要素のクラス名のカスタマイズ。

SampleApp12.java

/xdk/demo/java/jaxb/Sample12

属性名のカスタマイズ。

SampleApp13.java

/xdk/demo/java/jaxb/Sample13

グローバルsimpleTypeで指定されたjavaTypeカスタマイズ。javaTypeカスタマイズは、ユーザー定義クラスで宣言された解析および出力メソッドを指定します。

SampleApp14.java

/xdk/demo/java/jaxb/Sample14

TypeSafe Enumクラス名のカスタマイズ。


サンプル・プログラムのコンパイルおよび実行方法を説明するドキュメントは、同じディレクトリ内のREADMEにあります。基本手順は次のとおりです。

  1. ディレクトリを$ORACLE_HOME/xdk/demo/java/jaxbディレクトリ(UNIXの場合)または%ORACLE_HOME%\xdk\demo\java\jaxbディレクトリ(Windowsの場合)に変更します。

  2. 「Java XDK環境の設定」の説明に従って、環境変数が設定されていることを確認します。

  3. システム・プロンプトでmake(UNIXの場合)またはMake.bat(Windowsの場合)を実行します。makeユーティリティは、各サンプル・サブディレクトリに対して次の順次アクションを実行します。

    1. 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;
      
    2. javacユーティリティを実行してJavaクラスをコンパイルします。たとえば、makeユーティリティはSample1/generated/サブディレクトリ内のJavaクラス・ファイルに対して次のコマンドを実行します。

      cd ./Sample1/generated; $(JAVA_HOME)/bin/javac -classpath \
      "$(MAKE_CLASSPATH)" *.java
      
    3. javacユーティリティを実行して、前の手順でコンパイルされたクラスを使用するサンプルJavaアプリケーションをコンパイルします。たとえば、makeユーティリティはSampleApp1.javaプログラムをコンパイルします。

      cd ./Sample1; $(JAVA_HOME)/bin/javac -classpath "$(MAKE_CLASSPATH)" \
      SampleApp1.java
      
    4. サンプルJavaアプリケーションを実行し、結果をログ・ファイルに書き込みます。たとえば、makeユーティリティはSampleApp1クラスを実行し、出力をsample1.outに書き込みます。

      cd ./Sample1; $(JAVA_HOME)/bin/java -classpath "$(MAKE_CLASSPATH)" \SampleApp1 > sample1.out
      

JAXB Class Generatorコマンドライン・ユーティリティの使用

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のコマンドライン・オプション

オプション 用途

-help

ヘルプ・メッセージを出力します。

-version

バージョン番号を出力します。

-outputdir OutputDir

Javaソース・ファイルの生成先ディレクトリを指定します。スキーマに名前空間がある場合、プログラムでは、outputDirから参照されるパッケージ(名前空間に対応)にJavaコードが生成されます。デフォルトでは、現行ディレクトリはoutputDirです。

-schema SchemaFile

入力XMLスキーマを指定します。

-targetPkg targetPkg

ターゲット・パッケージ名を指定します。このオプションは、パッケージ名のバインディング・カスタマイズと、JAXB仕様で定義されているデフォルトのパッケージ名アルゴリズムをオーバーライドします。

-interface

インタフェースのみを生成します。

-verbose

生成されたクラスおよびインタフェースをリストします。

-defaultCus fileName

デフォルトのカスタマイズ・ファイルを生成します。

-extension

ベンダー固有の拡張を許可し、JAXB 1.0仕様の付録E.2に指定されている互換性ルールに厳密には従いません。これが指定されている場合、プログラムでは、表記法、置換グループ、属性など、JAXB 1.0でサポートされていない機能は無視されます。


JAXB Class Generatorコマンドライン・ユーティリティの使用: 例

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

XDKでサポートされていないJAXB機能

Oracle Database XDKにおけるJAXB仕様の実装では、次の機能はサポートされていません。

  • Javadocの生成

  • XML Schemaコンポーネント"any"および置換グループ


関連項目:

JAXB仕様は、http://java.sun.com/xml/downloads/jaxb.htmlを参照してください。

JAXB Class Generatorを使用したXMLの処理

この項の内容は次のとおりです。

複合型のバインディング

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>

Javaクラスの生成およびコンパイル

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複合型では、要素のシーケンス(namedoorNumberstreetおよびcity)を定義しました。したがって、Addressインタフェースには、4つの各要素に対するgetおよびsetメソッド署名が含まれます。たとえば、インタフェースには、<name>要素内のデータを取得するためのgetName()およびこの要素内のデータを変更するためのsetName()が含まれます。

Javaソース・ファイルはjavacを使用して次のようにコンパイルできます。

cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample3/generated
javac *.java

XMLデータの処理

Sample3.javaは、「Javaクラスの生成およびコンパイル」で生成したJavaクラス・ファイルを使用してsample3.xml文書を処理する方法を示します。サンプル・プログラムは、XMLデータ文書をアンマーシャリングしてマーシャリングし、生成されたクラスを使用して住所データを出力および変更します。

Sample3.javaプログラムでは、データを次のように処理します。

  1. XMLデータ文書のファイル名、および生成されたクラスを含むディレクトリの名前の文字列を作成します。この名前はパッケージ名です。次に例を示します。

    String fileName = "sample3.xml";
    String instancePath = "generated";
    
  2. JAXBContext.newInstance()を起動することにより、JAXBコンテンツをインスタンス化します。クライアント・アプリケーションは、コンテキスト・パスで初期化することにより、このクラスの新規インスタンスを取得します。パスには、Marshallerで使用可能なインタフェースを含むJavaパッケージ名のリストが含まれます。この方法を示す文は次のとおりです。

    JAXBContext jc = JAXBContext.newInstance(instancePath);
    
  3. Unmarshallerをインスタンス化します。Unmarshallerクラスは、XMLデータを新規に作成されたオブジェクトにデシリアライズし、オプションとしてXMLデータのアンマーシャリング時に検証を行うプロセスを管理します。この方法を示す文は次のとおりです。

    Unmarshaller u = jc.createUnmarshaller();
    
  4. XML文書をアンマーシャリングします。Unmarshaller.unmarshal()メソッドを起動して、sample3.xml文書をデシリアライズし、コンテンツ・ツリーをObjectとして戻します。fileToUrl()ヘルパー・メソッドを起動することにより、XMLファイル名からURLを作成できます。この方法を示す文は次のとおりです。

    Object obj = u.unmarshal(fileToURL(fileName));
    
  5. Marshallerをインスタンス化します。Marshallerクラスは、Javaコンテンツ・ツリーのXMLデータへのシリアライズのプロセスを管理します。この方法を示す文は次のとおりです。

    Marshaller m = jc.createMarshaller();
    
  6. コンテンツ・ツリーをマーシャリングします。Marshaller.marshal()メソッドを起動して、Unmarshallerから戻されたコンテンツ・ツリーObjectをマーシャリングします。DOMツリー、SAXコンテンツ・ハンドラ、変換結果または出力ストリームをシリアライズできます。次の文は、マークアップを含めたXMLデータを出力ストリームとしてシリアライズします。

    m.marshal(obj, System.out);
    

    デフォルトでは、Marshallerは出力ストリームにXMLデータを書き込むときにUTF-8エンコーディングを使用します。

  7. XML文書のコンテンツを出力します。プログラムでは、コンテンツ・ツリーとMarshallerをパラメータとして受け入れるprocess()メソッドを実装します。

    処理の最初のステージでは、XMLマークアップのないXML文書内のデータを出力します。メソッドは、Marshallerにより生成されたObjectMyAddress型にキャストします。このメソッドは、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" );
    ...
    
  8. 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にバインドします。

Javaクラスの生成およびコンパイル

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複合型では、要素のシーケンス(titleownerおよびid)を定義しました。したがって、Addressインタフェースには、各要素に対するgetおよびsetメソッド署名が含まれます。たとえば、インタフェースには、<title>要素内のデータを取得するためのgetTitle()およびこの要素内のデータを変更するためのsetTitle()が含まれます。

Javaソース・ファイルはjavacを使用して次のようにコンパイルできます。

cd $ORACLE_HOME/xdk/demo/java/jaxb/Sample10/jaxbcustomized/sample10
javac *.java

XMLデータの処理

Sample10.javaソース・ファイルは、「Javaクラスの生成およびコンパイル」で生成したクラス・ファイルを使用してsample10.xml文書のデータを処理する方法を示しています。サンプル・プログラムは、XML文書をアンマーシャリングし、そのコンテンツを出力し、XMLを標準出力にマーシャリングします。

Sample10.javaプログラムでは、XMLデータを次のように処理します。

  1. XMLデータ文書のファイル名、および生成されたクラスを含むディレクトリの名前の文字列を作成します。この名前はパッケージ名です。次に例を示します。

    String fileName = "sample10.xml";
    String instancePath = "jaxbcustomized.sample10";
    
  2. JAXBContext.newInstance()メソッドを起動することにより、JAXBコンテンツをインスタンス化します。この方法を示す文は次のとおりです。

    JAXBContext jc = JAXBContext.newInstance(instancePath);
    
  3. Unmarshallerを作成します。この方法を示す文は次のとおりです。

    Unmarshaller u = jc.createUnmarshaller();
    
  4. XML文書をアンマーシャリングします。プログラムは、文書を2回アンマーシャリングします。最初にObjectを戻し、次にキャストを使用してMyBusinessオブジェクトを戻します。この方法を示す文は次のとおりです。

    Object obj = u.unmarshal(fileToURL(fileName));
    jaxbcustomized.sample10.MyBusiness bus =
             (jaxbcustomized.sample10.MyBusiness) u.unmarshal(fileToURL(fileName));
    
  5. 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();
    
  6. Marshallerを作成します。この方法を示す文は次のとおりです。

    Marshaller m = jc.createMarshaller();
    
  7. Marshallerを構成します。setProperty()を起動して、Marshallerの様々なプロパティを構成できます。JAXB_FORMATTED_OUTPUT定数は、MarshallerがXMLデータを改行とインデントで書式設定する必要があることを指定します。次の文は、この方法を示します。

    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
    
  8. コンテンツ・ツリーをマーシャリングします。次の文は、マークアップを含めたXMLデータを出力ストリームとしてシリアライズします。

    m.marshal(bus, System.out);
    

    デフォルトでは、Marshallerは出力ストリームにXMLデータを書き込むときにUTF-8エンコーディングを使用します。