Menu Close

第33章 XML 要素の使用

概要

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

概要

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

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

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

XML スキーママッピング

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

name 属性に加えて、element 要素には 表33.1「要素の定義に使用される属性」に一覧表示される任意の属性があります。

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

属性説明

type

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

nillable

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

abstract

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

substitutionGroup

この要素で置き換えることのできる要素の名前を指定します。型置換の使用に関する詳細は、「37章要素の置換」を参照してください。

default

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

fixed

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

例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 スキーマの element 要素の name 属性値を指定します。

namespace

要素が定義される namespace を指定します。この要素がターゲット 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);
   }