先週はスキーマからJavaへのバインディングをカスタマイズする方法について説明しました。その中で<javaType>要素だけは説明を行ないませんでした。今週は,この<javaType>要素と,Javaからスキーマへのバインディングをカスタマイズする方法について紹介していきます。

データ型のカスタマイズ

<javaType>要素はXMLの型からJavaの型への対応付けをカスタマイズするための要素です。

通常はXML SchemaのintはJavaのintに対応づけられます。たとえば,XML SchemaのintをJavaのlongで扱いたい,といった場合に<javaType>要素を使用します。

<javaType>要素は次のように記述します。

<javaType name="javaType"
        [ xmlType="xmlType" ]
        [ parseMethod="parseMethod" ]
        [ printMethod="printMethod" ]>

name属性だけが必須,残りの3つの属性はオプションです。

name属性がJavaの型を示し,xmlTypeがXML Schemaの型を示します。xmlType属性がオプションなのは,<property>要素と共に使用するときなど,XMLの型が自明な場合があるためです。

name属性の値にはパッケージまで含めたクラス名もしくはプリミティブ(たとえば,intなど)を指定します。

parseMethod属性とprintMethod属性については後述します。

<javaType>要素が使用できるのは,次の3つの場合です。

  • <globalBindings>要素
  • <property>要素
  • simpleTypeの定義

それぞれの使い方を見ていきましょう。まずは<globalBindings>要素での使い方です。

たとえば,次のようなスキーマを考えてみます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0"
           targetNamespace="http://www.javainthebox.net/sample" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
   
  <xs:element name="point">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="x" type="xs:float"/>
        <xs:element name="y" type="xs:float"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

floatで座標を表すXML Schemaです。通常であれば,XML SchemaのfloatはJavaのfloatに対応づけられています。これをJavaのjava.lang.Doubleクラスに対応づけてみます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0"
           targetNamespace="http://www.javainthebox.net/sample" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
           jxb:version="2.1">
   
  <xs:annotation>
    <xs:appinfo>
      <jxb:globalBindings>
        <jxb:javaType name="java.lang.Double"
                      xmlType="xs:float"
                      parseMethod="new"
                      printMethod="toString"/>
      </jxb:globalBindings>
    </xs:appinfo>
  </xs:annotation>
  
  <xs:element name="point">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="x" type="xs:float"/>
        <xs:element name="y" type="xs:float"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

<globalBindings>要素の中で<javaType>要素を使用すると,xmlType属性で指定した型を使っている箇所はすべて,nameに対応づけられます。

ここでは,xs:floatをjava.lang.Doubleに対応づけています。

対応づけるとしても,どのように対応づけるかを指定しなければなりません。具体的にいえば,文字列で記述されたXMLドキュメントをname属性で指定された型のオブジェクトに変換しなくてはなりません。また,オブジェクトを文字列に変換するときも同じです。

この変換に使用するのが,<javaType>要素の残りの2つの属性,parseMethod属性とprintMethod属性です。