この章の内容は次のとおりです。
この項では、単純なJava値をXMLテキスト・ノードに直接マップする方法をいくつか示します。
例4-1のXMLスキーマであると仮定して、図4-1は、対応するXML文書内にある属性へのXMLダイレクト・マッピングを示します。
例4-1 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:attribute name="id" type="xsd:integer"/>
</xsd:complexType>
</xsd:schema>
例4-2は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。必要なのは、JAXBの標準的な@XmlAttribute注釈のみです。
例4-2 @XmlAttribute注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlAttribute
private Integer id;
...
}
例4-3は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
この項では、次を実行した場合のXMLダイレクト・マッピングの使用方法について説明します。
例4-4のXMLスキーマであると仮定して、図4-2は、対応するXML文書内にある順序での個々のテキスト・ノードへのXMLダイレクト・マッピングを示します。
例4-4 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string"/>
<xsd:element name="last-name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-1は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。ここでは、JAXBの標準的な@XmlElement注釈が、カスタマイズされた要素名とともに使用されます。
例4-5 @XmlElement注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="first-name")
private String firstName;
@XmlElement(name="last-name")
private String lastName;
...
}
例4-5では、マップされた属性に対してXML要素名を明示的に指定しました。これは省略可能な構成であり、名前を明示的に設定しなくても、XML要素はJava属性名を照合するのみで、XMLでは<firstName>Jane</firstName>のようになります。JAXBの名前バインディング・アルゴリズムの詳細は、『Java Architecture for XML Binding (JAXB) Specification』(http://jcp.org/en/jsr/detail?id=222)の「Appendix D: Binding XML Names to Java Identifiers」を参照してください。
例4-6は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。カスタム要素のnameを指定するには、name属性を使用します。
例4-7のXMLスキーマであると仮定して、図4-3は、対応するXML文書内のサブ要素にあるテキスト・ノードへのXMLダイレクト・マッピングを示します。
例4-7 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="personal-info">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="first-name" type="xsd:string"/>
<xsd:element name="last-name" type="xsd:string"/>
<xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-8は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。ここでは、単純な要素名のカスタマイズではなく、新しいXML構造を実際に導入しているので、EclipseLinkの@XmlPath注釈が使用されています。
例4-8 @XmlPath注釈の使用
package example;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlPath("personal-info/first-name/text()")
private String firstName;
@XmlPath("personal-info/last-name/text()")
private String lastName;
...
}
例4-9は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。ここでは、カスタマイズされたXMLパスがxml-path属性に定義されます。
例4-9 xml-path属性の使用
...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="firstName" xml-path="personal-info/first-name/text()"/>
<xml-element java-attribute="lastName" xml-path="personal-info/last-name/text()"/>
</java-attributes>
</java-type>
...
例4-10のXMLスキーマであると仮定して、図4-4は、対応するXML文書の位置によるテキスト・ノードへのXMLダイレクト・マッピングを示します。
例4-10 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="name" type="xsd:string" maxOccurs="2"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-11は、Javaでのこのマッピングの構成方法を示しています。再び、より複雑なXMLパスのカスタマイズに向けて、EclipseLinkの@XmlPath注釈が使用されています。
例4-11 @XmlPath注釈の使用
package example;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlPath("name[1]/text()")
private String firstName;
@XmlPath("name[2]/text()")
private String lastName;
...
}
例4-12は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-13のXMLスキーマであると仮定して、図4-5は、対応するXML文書内にある単純なテキスト・ノードへのXMLダイレクト・マッピングを示します。
例4-13 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="phone-number" type="xsd:string"/> </xsd:schema>
例4-14は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。この場合は、@XmlValue注釈が使用されます。
例4-14 @XmlValue注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="phone-number")
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumber {
@XmlValue
private String number;
...
}
例4-15は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
ほとんどの場合、EclipseLinkではXML文書のターゲット書式を決定できます。ただし、EclipseLinkで使用可能な複数のターゲットから、1つを指定する必要がある場合があります。たとえば、java.util.Calendarは、スキーマdate、time、dateTimeのノードのいずれかにマーシャリングできる場合があり、byte[]は、スキーマhexBinaryまたはbase64Binaryノードにマーシャリングできる場合があります。
例4-16と図4-6のXMLスキーマは、JavaのCalendarオブジェクトからXMLのdateフィールドへのXMLダイレクト・マッピングを示します。
例4-16 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="hire-date" type="xsd:date"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-17は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。ここでは、マーシャリングされたXMLに出現するデータ型を指定するために、@XmlSchemaTypeが使用されています。
例4-17 @XmlSchemaType注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="hire-date")
@XmlSchemaType(name="date")
private Calendar hireDate;
...
}
例4-18は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-18 マッピングの定義
...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="hireDate" name="hire-date">
<xml-schema-type name="date"/>
</xml-element>
</java-attributes>
</java-type>
...
例4-19と図4-7は、別々のバイナリ型の2つの異なるテキスト・ノードへのXMLダイレクト・マッピングを示しています。
例4-19 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="resume" type="xsd:base64Binary"/>
<xsd:element name="picture" type="xsd:hexBinary"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-20は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。デフォルトでは、JAXBによってbyte[]がbase64Binaryにマーシャリングされるので、再開マッピングに必要となるものは特にありません。hexBinaryフィールドにマップするには、@XmlSchemaType注釈でXMLタイプを指定する一方、@XmlJavaTypeAdapterでは、値への変換を担当するアダプタ・クラス(この場合は組込みJAXB HexBinaryAdapter)を指定します。
例4-20 @XmlSchemaType注釈および@XmlJavaTypeAdapter注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
private byte[] resume;
@XmlSchemaType(name="hexBinary")
@XmlJavaTypeAdapter(HexBinaryAdapter.class)
private byte[] picture;
...
}
例4-21は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-21 マッピングの定義
...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="resume"/>
<xml-element java-attribute="picture">
<xml-schema-type name="hexBinary"/>
<xml-java-type-adapter value="javax.xml.bind.annotation.adapters.HexBinaryAdapter"/>
</xml-element>
</java-attributes>
</java-type>
...
ノードのタイプをXMLスキーマで定義していない場合は、XMLダイレクト・マッピングを構成してxsi:type属性を使用し、タイプ情報を提供できます。
例4-22のXMLスキーマであると仮定して、図4-8は、対応するXML文書にマップできるJavaクラスを示します。
例4-22 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="phone-number" type="phone-number-type"/>
<xsd:complexType name="phone-number-type">
<xsd:sequence>
<xsd:element name="area-code" type="anySimpleType"/>
<xsd:element name="number" type="anySimpleType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
図4-9は、XML文書のシンプル・タイプ・トランスレータによるXMLダイレクト・マッピングを示します。このXML文書は前述のスキーマに準拠しています。
例4-23は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。
例4-23 マッピングのサンプル
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="phone-number")
public class PhoneNumber {
@XmlElement(name="area-code")
private Object areaCode;
private Object number;
...
}
例4-24は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
この項では、単純なJava値のコレクションをXMLテキスト・ノードに直接マップする方法をいくつか示します。
例4-25のXMLスキーマであると仮定して、図4-10では、対応するXML文書内にある要素へのJavaコレクションのマッピングを示します。
例4-25 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="email-address" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
例4-26は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。必要なのは、JAXBの標準的な@XmlElement注釈のみです。
例4-26 @XmlElement注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="email-address")
private List<String> emailAddress;
...
}
例4-27は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-28のXMLスキーマであると仮定して、図4-11では、対応するXML文書内にある要素へのJavaコレクションのマッピングを示します。ここでは、コレクションの要素を整理するためにグループ化要素を使用しています。
例4-28 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="customer" type="customer-type"/>
<xsd:complexType name="customer-type">
<xsd:sequence>
<xsd:element name="email-address" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
図4-11 グループ化要素によるテキスト・ノードへのXMLダイレクト・コレクション・マッピング

例4-29は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。グループ化要素は、@XmlElementWrapper注釈を使用して指定します。
例4-29 @XmlElementWrapper注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlElement(name="email-address")
@XmlElementWrapper(name="email-addresses")
private List<String> emailAddresses;
...
}
例4-30は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-31のXMLスキーマであると仮定して、図4-12では、対応するXML文書内にあるxsd:listタイプへのマッピングを示します。このマッピングを使用すると、単純なJavaオブジェクトのコレクションを、XML内で空白で区切られたトークンのStringとして表すことができます。ここで、タスク・リストには、Design、Code、Testの3つのエントリが含まれています。
例4-31 XMLスキーマのサンプル
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="employee" type="employee-type"/>
<xsd:complexType name="employee-type">
<xsd:sequence>
<xsd:element name="tasks" type="tasks-type"/>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="tasks-type">
<xsd:list itemType="xsd:string"/>
</xsd:simpleType>
</xsd:schema>
例4-32は、EclipseLinkでこのマッピングを取得するためにJavaクラスに注釈を付ける方法を示しています。
例4-32 @XmlList注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Employee {
@XmlList
private List<String> tasks;
...
}
例4-33は、EclipseLinkのOXMメタデータ形式でマッピング情報を定義する方法を示しています。
例4-34に示すように、@XmlListは、@XmlAttributeまたは@XmlValueと組み合せて使用することもできます。このコレクションは、属性内のスペース区切りの文字列として表されます。
例4-34 Javaの注釈
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
@XmlAttribute
@XmlList
private List<Integer> ids;
...
}
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="phone-numbers")
@XmlAccessorType(XmlAccessType.FIELD)
public class PhoneNumbers {
@XmlValue
@XmlList
private List<String> numbers;
...
}
例4-35 EclipseLink OXMメタデータ
...
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-attribute java-attribute="ids" xml-list="true"/>
</java-attributes>
</java-type>
...
...
<java-type name="PhoneNumbers">
<xml-root-element name="phone-numbers"/>
<java-attributes>
<xml-value java-attribute="numbers" xml-list="true"/>
</java-attributes>
</java-type>
...
標準的なJAXBでは、Javaフィールドごとに指定できるマッピングはせいぜい1つです。EclipseLink MOXy 2.3以降では、OXMメタデータを使用して1つのプロパティに複数のマッピングを作成できます。ただし、読取り可能なマッピングはせいぜい1つです(それ以外は「書込み専用」です)。
この例では、次のJavaクラスを使用します。
例4-37 Javaクラスのサンプル
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class CustomQuoteRequest {
private int requestId;
private String currencyPairCode;
}
例4-38は、EclipseLinkのOXMメタデータ形式でcurrencyPairCodeの複数のマッピングを定義する方法を示しています。2番目のマッピングではwrite-only="true"と指定されていることに注意してください。
例4-38 XMLスキーマのサンプル
...
<java-type name="CustomQuoteRequest">
<xml-root-element/>
<java-attributes>
<xml-element java-attribute="requestId" name="id"/>
<xml-attribute java-attribute="currencyPairCode" xml-path="req/info/instrmt/@sym"/>
<xml-attribute java-attribute="currencyPairCode" xml-path="req/info/leg/token/@sym" write-only="true"/>
</java-attributes>
</java-type>
...
Java列挙は、@XmlEnum注釈と@XmlEnumValue注釈を使用してXMLにマップできます。
次のスキーマは、XML列挙を示しています。
例4-40 XMLスキーマのサンプル
<xs:simpleType name="CustomerType">
<xs:restriction base="xs:string"/>
<xs:enumeration value="PROMO_CUSTOMER"/>
<xs:enumeration value="NEW_CUSTOMER"/>
<xs:enumeration value="VIP"/>
<xs:enumeration value="NORMAL"/>
</xs:restriction>
</xs:simpleType>
enum定数名自体がXML表現に十分な場合は、@XmlEnum注釈を使用するだけです。
例4-41 @XmlEnum注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
private CustomerType type = CustomerType.NEW_CUSTOMER;
@XmlEnum(String.class)
private enum CustomerType { PROMO_CUSTOMER, NEW_CUSTOMER, VIP, NORMAL }
...
}
例4-42は、EclipseLinkのOXMメタデータでこのマッピングを定義する方法を示しています。
例4-42 XMLマッピングのサンプル
...
<xml-enums>
<xml-enum java-enum="CustomerType" value="java.lang.String">
<xml-enum-value java-enum-value="PROMO_CUSTOMER">PROMO_CUSTOMER</xml-enum-value>
<xml-enum-value java-enum-value="NEW_CUSTOMER">NEW_CUSTOMER</xml-enum-value>
<xml-enum-value java-enum-value="VIP">VIP</xml-enum-value>
<xml-enum-value java-enum-value="NORMAL">NORMAL</xml-enum-value>
</xml-enum>
</xml-enums>
<java-types>
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="type" type="CustomerType"/>
</java-attributes>
</java-type>
</java-types>
...
XMLにマーシャリングすると、Customerは次のようになります。
<customer> <type>NEW_CUSTOMER</type> </customer>
次のXMLスキーマ列挙が与えられたとします。
例4-43 XMLスキーマのサンプル
<xs:simpleType name="CustomerType">
<xs:restriction base="xs:int">
<xs:enumeration value="1"/>
<xs:enumeration value="2"/>
<xs:enumeration value="3"/>
<xs:enumeration value="4"/>
</xs:restriction>
</xs:simpleType>
これをJavaでモデル化するには、enum定数ごとに、XML値を提供するために@XmlEnumValue注釈が使用されます。
例4-44 @XmlEnumValue注釈の使用
package example;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
private CustomerType type = CustomerType.NEW_CUSTOMER;
@XmlEnum(Integer.class)
private enum CustomerType {
@XmlEnumValue("1") PROMO_CUSTOMER,
@XmlEnumValue("2") NEW_CUSTOMER,
@XmlEnumValue("3") VIP,
@XmlEnumValue("4") NORMAL;
...
}
例4-45は、EclipseLinkのOXMメタデータでこのマッピングを定義する方法を示しています。
例4-45 XMLマッピングのサンプル
...
<xml-enums>
<xml-enum java-enum="CustomerType" value="java.lang.Integer">
<xml-enum-value java-enum-value="PROMO_CUSTOMER">1</xml-enum-value>
<xml-enum-value java-enum-value="NEW_CUSTOMER">2</xml-enum-value>
<xml-enum-value java-enum-value="VIP">3</xml-enum-value>
<xml-enum-value java-enum-value="NORMAL">4</xml-enum-value>
</xml-enum>
</xml-enums>
<java-types>
<java-type name="Customer">
<xml-root-element name="customer"/>
<java-attributes>
<xml-element java-attribute="type" type="CustomerType"/>
</java-attributes>
</java-type>
</java-types>
...
XMLにマーシャリングすると、新しいCustomerは次のようになります。
<customer> <type>2</type> </customer>