この章の内容は次のとおりです。
この項では、単純な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>