今週からJAXBのバインディングをカスタマイズする方法について説明していきます。

とはいうものの,JAXBのバインディングはほとんどの場合,カスタマイズする必要がありません。しかし,たとえばスキーマからJavaのクラスを生成する時,Javadocを記述したいということがあるかもしれません。また,名前の衝突が発生してしまうこともあります。

このような場合にバインディングをカスタマイズし,問題を解消するようにします。

バインディングにはスキーマからJavaと,Javaからスキーマの両方向がありますが,それぞれカスタマイズを行なうことができます。しかし,Javaからスキーマへのバインディングはアノテーションが使用できるため,カスタマイズを行なうことは少ないはずです。

そこで,今週と来週でスキーマからJavaへのバインディングにおけるカスタマイズ,再来週にJavaからスキーマへのバインディングにおけるカスタマイズについて説明します。

インラインと外部ファイル

スキーマからJavaへのバインディングをカスタマイズするには2つの手法があります。

  • XML Schemaファイルにカスタマイズのための情報を埋め込む(インラインカスタマイズ)
  • 外部のファイルにカスタマイズのための情報を記述する(外部ファイルによるカスタマイズ)

インラインカスタマイズはカスタマイズしたい要素に直接記述できるので,どのようなカスタマイズを行なうかが一目瞭然です。しかし,スキーマの定義の可読性は下がってしまいます。

外部ファイルに記述する場合,カスタマイズを行なう対象をXPathで指定しなくてはならず,やや煩雑です。しかし,スキーマファイルを第三者が所有していて,変更できない場合などに重宝します。また,スキーマは変更しないため,スキーマ自体の可読性は維持されます。

このように2つの手法の特徴は異なるので,用途に応じて使い分けをするようにしましょう。

それぞれの手法は記述方法も異なります。

インラインカスタマイズは,XML Schemaで定義されているカスタマイズ用の<annotation>要素と<appinfo>要素を組み合わせて記述します。

<xs:annotation>
   <xs:appinfo>
      ここにカスタマイズのための情報を記述する
   </xs:appinfo>
</xs:annotation>

xsはXML Schemaの名前空間を表すプリフィックスです。

<annotation>要素は<schema>要素や,<complexType>要素,<element>要素などの子要素として記述することができます。したがって,カスタマイズを行ないたい部分に<aoontation>要素を埋め込むことができます。

一方,外部ファイルに記述する方法は<bindings>要素を使用して記述します。

<jxb:bindings schemaLocation = "スキーマファイルのURI">
   <jxb:bindings node = "XPathによるノードの指定">
      ここにカスタマイズのための情報を記述する
   <jxb:bindings>
</jxb:bindings>

jxbはJAXBの名前空間を表すプリフィックスです。

<bindings>要素は入れ子にして使用することができます。一番外側の<bindings>要素では,schemaLocation属性でXML Schemaファイルを指定します。

<bindings>要素は,カスタマイズの対象となるノードを示すためにnode属性を使用します。node属性はXPathを用いて記述します。

このXPath式は,多段で指定することが可能です。つまり,<bindings>要素を入れ子にし,複数のXPath式でノードを指定することができるのです。このため,XPath式の記述を簡略することができます。

使い方の例として,名前空間とは異なるパッケージでクラスを生成してみましょう。また,スキーマとプロパティで名前を変更することも行なってみます。

まず,対象となるXML Schemaを次に示します。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0"
    targetNamespace="http://www.javainthebox.net/music" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="album">
    <xs:complexType>
      <xs:attribute name="title" type="xs:string"/>
      <xs:attribute name="credit" type="xs:string"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

このまま,xjcでJavaのクラスを生成させると,net.javainthebox.musicパッケージにクラスを生成します。それをnet.javainthebox.sampleに変更してみます。また,credit属性をartistプロパティに対応づけてみます。