第33章 XML 要素の使用

概要

XML スキーマ要素は、XML ドキュメント内の要素のインスタンスを定義するために使用されます。要素は、XML スキーマドキュメントのグローバルスコープで定義されるか、複合型のメンバーとして定義されます。それらがグローバルスコープで定義されている場合、Apache CXF はそれらを JAXB 要素クラスにマップし、操作を容易にします。

概要

XML ドキュメントの要素インスタンスは、XML スキーマドキュメントのグローバルスコープの XML スキーマ element 要素によって定義されます。Java 開発者が要素を操作するのを容易にするために、Apache CXF はグローバルにスコープ設定された要素を特別な JAXB 要素クラスにマッピングするか、またはコンテンツ型に一致するように生成された Java クラスにマッピングします。

要素がどのようにマッピングされるかは、要素が type 属性によって参照される名前付き型を使用して要素を定義されるか、または要素がインライン型定義を使用して定義されるかによって異なります。インライン型定義で定義された要素は、Java クラスにマップされます。

インライン型はスキーマ内の他の要素で再利用できないため、要素は名前付き型を使用して定義することをお勧めします。

XML スキーママッピング

XML Schema では、要素は element 要素を使用して定義されます。element 要素には必須属性が 1 つあります。name は、XML ドキュメントに表示される要素の名前を指定します。

name 属性 要素 の他に、表33.1「要素の定義に使用される属性」 にリストされている任意の属性があります。

表33.1 要素の定義に使用される属性

属性説明

type

要素の型を指定します。タイプは、任意の XML スキーマプリミティブ型またはコントラクトで定義された任意の名前付き複合型にすることができます。この属性が指定されていない場合は、インラインタイプ定義を含める必要があります。

nillable

要素をドキュメントから完全に除外できるかどうかを指定します。nillabletrue に設定されている場合、要素はスキーマを使用して生成したドキュメントから省略できます。

abstract

要素をインスタンスドキュメントで使用できるかどうかを指定します。true は、要素がインスタンスドキュメントに表示されないことを示します。代わりに、この要素の QName が含まれる substitutionGroup 属性が含まれる別の要素がこの要素に表示される必要があります。この属性がコード生成にどのように影響するかについては、「抽象要素の Java マッピング」 を参照してください。

substitutionGroup

この要素で置き換えることができる要素の名前を指定します。タイプ置換の使用の詳細については、37章元素置換 を参照してください。

default

要素のデフォルト値を指定します。この属性がコード生成にどのように影響するかについては、「デフォルト値を持つ要素の Java マッピング」 を参照してください。

固定:

要素の固定値を指定します。

例33.1「単純な XML スキーマ要素の定義」 は簡単な要素定義を示しています。

例33.1 単純な XML スキーマ要素の定義

<element name="joeFred" type="xsd:string" />

要素は、インライン型定義を使用して独自の型を定義することもできます。インライン型は、complexType 要素または simpleType 要素のいずれかを使用して指定します。データの型が複雑か単純かを指定すると、各型のデータに使用できるツールを使用して、必要な任意のタイプのデータを定義できます。

例33.2「インラインタイプの XML スキーマ要素定義」 は、インラインタイプ定義を含む要素定義を示しています。

例33.2 インラインタイプの XML スキーマ要素定義

<element name="skate">
  <complexType>
    <sequence>
      <element name="numWheels" type="xsd:int" />
      <element name="brand" type="xsd:string" />
    </sequence>
  </complexType>
</element>

名前付きタイプの要素の Java マッピング

デフォルトでは、グローバルに定義されている要素は JAXBElement<T> オブジェクトにマップされます。このオブジェクトは、element 要素の type 属性の値によって決定されます。プリミティブ型の場合、テンプレートクラスは、「ラッパークラス」 で説明されているラッパークラスマッピングを使用して派生します。複合型の場合、複合型をサポートするために生成された Java クラスがテンプレートクラスとして使用されます。

マッピングをサポートし、要素の QName に関する開発者の不必要な心配を軽減するために、例33.3「グローバルスコープ要素のオブジェクトファクトリーメソッド」 に示すように、グローバルに定義された要素ごとにオブジェクトファクトリーメソッドが生成されます。

例33.3 グローバルスコープ要素のオブジェクトファクトリーメソッド

public class ObjectFactory {

    private final static QName _name_QNAME = new QName("targetNamespace", "localName");

    ...

    @XmlElementDecl(namespace = "targetNamespace", name = "localName")
    public JAXBElement<type> createname(type value);

}

たとえば、例33.1「単純な XML スキーマ要素の定義」 で定義された要素結果は、例33.4「単純な要素のオブジェクトファクトリー」 に示すオブジェクトファクトリーメソッドになります。

例33.4 単純な要素のオブジェクトファクトリー

public class ObjectFactory {

    private final static QName _JoeFred_QNAME = new QName("...", "joeFred");

    ...

    @XmlElementDecl(namespace = "...", name = "joeFred")
    public JAXBElement<String> createJoeFred(String value);

}

例33.5「グローバルスコープ要素の使用」 は、Java でグローバルスコープの要素を使用する例を示しています。

例33.5 グローバルスコープ要素の使用

JAXBElement<String> element = createJoeFred("Green");
String color = element.getValue();

WSDL で名前付きタイプの要素を使用する

グローバルにスコープ設定された要素を使用してメッセージ部分を定義する場合、生成される Java パラメーターは JAXBElement<T> のインスタンスではありません。代わりに、通常の Java タイプまたはクラスにマップされます。

例33.6「メッセージ部分として要素を使用する WSDL」 に示される WSDL フラグメントの場合、結果のメソッドは String 型のパラメーターを持ちます。

例33.6 メッセージ部分として要素を使用する WSDL

<?xml version="1.0" encoding=";UTF-8"?>
<wsdl:definitions name="HelloWorld"
                  targetNamespace="http://apache.org/hello_world_soap_http"
                  xmlns="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                  xmlns:tns="http://apache.org/hello_world_soap_http"
                  xmlns:x1="http://apache.org/hello_world_soap_http/types"
                  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <schema targetNamespace="http://apache.org/hello_world_soap_http/types"
            xmlns="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"><element name="sayHi">
      <element name="sayHi" type="string"/>
      <element name="sayHiResponse" type="string"/>
    </schema>
  </wsdl:types>

  <wsdl:message name="sayHiRequest">
    <wsdl:part element="x1:sayHi" name="in"/>
  </wsdl:message>
  <wsdl:message name="sayHiResponse">
    <wsdl:part element="x1:sayHiResponse" name="out"/>
  </wsdl:message>

  <wsdl:portType name="Greeter">
    <wsdl:operation name="sayHi">
      <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/>
      <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>

例33.7「グローバル要素を一部として使用する Java メソッド」に、sayHi 操作の生成されたメソッド署名を示します。

例33.7 グローバル要素を一部として使用する Java メソッド

StringsayHiStringin

インラインタイプの要素の Java マッピング

要素がインラインタイプを使用して定義されている場合、他のタイプを Java にマッピングするために使用されるのと同じルールに従って Java にマッピングされます。単純型の規則については、34章単純型の使用 で説明しています。複合型のルールについては、35章複雑なタイプの使用 で説明しています。

インラインの型定義を持つ要素に対して Java クラスが生成されると、生成されたクラスは @XmlRootElement アノテーションで装飾されます。@XmlRootElement アノテーションには、namenamespace の 2 つの便利なプロパティーがあります。属性については、表33.2「@XmlRootElement アノテーションのプロパティー」 で説明されています。

表33.2 @XmlRootElement アノテーションのプロパティー

プロパティー説明

name

XML Schema element 要素の name 属性の値を指定します。

namespace

要素が定義されている名前空間を指定します。この要素がターゲット名前空間で定義されている場合、プロパティーは指定されていません。

要素が以下の条件を 1 つ以上満たす場合、@XmlRootElement アノテーションは使用されません。

  • 要素の nillable 属性が true に設定されます。
  • 要素は、置換グループのヘッド要素です

    置換グループの詳細については、37章元素置換 を参照してください。

抽象要素の Java マッピング

要素の abstract 属性を true に設定すると、タイプのインスタンスをインスタンス化するオブジェクトファクトリーメソッドが生成されません。要素がインライン型を使用して定義されている場合、インライン型をサポートする Java クラスが生成されます。

デフォルト値を持つ要素の Java マッピング

要素の default 属性が使用される場合、defaultValue プロパティーが生成された @XmlElementDecl アノテーションに追加されます。たとえば、で定義された要素 例33.8「デフォルト値の XML スキーマ要素」 結果は、例33.9「デフォルト値を持つ要素のオブジェクトファクトリーメソッド」 に示すオブジェクトファクトリーメソッドになります。

例33.8 デフォルト値の XML スキーマ要素

<element name="size" type="xsd:int" default="7"/>

例33.9 デフォルト値を持つ要素のオブジェクトファクトリーメソッド

   @XmlElementDecl(namespace = "...", name = "size", defaultValue = "7")
   public JAXBElement<Integer> createUnionJoe(Integer value) {
       return new JAXBElement<Integer>(_Size_QNAME, Integer.class, null, value);
   }