Home on 246ne ] [ XXXへ ]

XMLの定義

TAKAHASHI, Toru
2010年10月27日着手
はじめに
JavaプログラムでXMLを扱う場合に、XMLの定義、プログラムとのやり取り、XMLデータの作成についての一例をまとめる。

 

XML構造の定義

プログラムをまたがったり、人間がデータを作成しプログラムに入れる、あるいはその逆を行うときに、XMLを使うのが一つの方向性となっており、JavaにはXMLを扱うための数多くの機能(ライブラリ)が備わっています。

そこで、プログラムの設計上、XML構造の定義をする必要があります。

XML構造の定義には、検証可能で、かつプログラムの自動生成が見込まれるスキーマ定義を活用するのが便利です。スキーマには過去いろいろないきさつがありましたが、現時点ではXML Schemaを使うのが汎用性が高いです。

XML Schemaの記述

ここでは、XMLのデータ構造として以下のような階層を持つものを例題とします。

◇気象計測
      |    
      +---*◇計測値
               +--- □日時 年月日時分秒を表す
               +--- ◇温度 摂氏を10進小数で表す
               +--- ◇湿度 %を10進小数で表す
               +--- ◇風向 北を0度として時計回りを正とする角度で表す
               +--- ◇風速 mで10進整数で表す
凡例:◇ 要素
   □ 属性
      * 複数(1:多)

XMLデータのイメージは以下です。

<気象計測>
  <計測値 日時="XXXX">
    <温度>XX.X</温度>
    <湿度>XX.X</湿度>
    <風向>XXX</風向>
    <風速>X</風速>
  </計測値>
    :
</気象計測>

XMLスキーマの定義をしていきます。なお、名前空間を使った本格的な設計はいずれすることとし、ここでは名前空間を指定しない記述をします。

ステップ・バイ・ステップでXMLスキーマ定義をする

XMLスキーマ記述用のファイルを開く

まずは、好みのエディタで、XMLスキーマを記述するため新規ファイルを開きます。ファイル名は、weather.xsdとします。

XML宣言を記述する

XML Schemaを使った記述もXMLなので、最初にXML宣言を記述します。

<?xml version="1.0" encoding="UTF-8"?>

ファイルの文字コードはUTF-8で作成することにしたので、encodingにUTF-8を指定しました。

XML Schemaの最上位要素の記述

XML Schemaの最上位要素はschemaなので、これを記述します。XML Schemaの要素は名前空間付きで使用するので(使用しないでよかは不明ですが)、最上位要素schemaのところで名前空間の宣言を記述をします。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

</xs:schema>

これから定義する気象計測のXMLボキャブラリに、名前空間を定義するか、名前空間は定義しないか(カメレオン・スキーマ)の選択肢がありますが、最初のステップとしてはなしで作成します。

定義したいスキーマの最上位要素<気象計測>の宣言と型定義を記述
  <xs:element name="気象計測">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="計測値" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

要素を宣言するときは型を指定する必要があります。

XML Schemaでは、要素の宣言をelementで記述します。要素のタグ名は、name属性に記述した文字列になります。
今回の「気象計測」は、中に入れ子で要素を持つので、その型はXML SchemaではcomplexTypeとなります。complexTypeは、element要素の子要素でも記述できますし(ローカル型定義)、element要素の外側でも記述できます。外側で型を定義するときは、型の名前を与えることになり、複数のelementから利用することが可能になります(グローバル型定義)。

「気象計測」の子要素になる「計測値」は、複数個を記述できるように、sequence要素で定義します。そして、sequenceの子要素で計測値要素があることを記述しています。ここでは、「計測値」の型定義はせず参照(ref)のみとし、ただし、「気象計測」の子要素として何個リストできるかの範囲を指定しています(0以上最大値)。子要素となる計測値はref属性があるので、型定義はrefで関連するCompountTypeの記述箇所で行います。

型の定義は、要素間の入れ子関係の定義とは別の場所で記述した方が、可読性が高いと思います。

計測値の定義を記述
 <xs:element name="計測値">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="温度" />
        <xs:element ref="湿度" />
        <xs:element ref="風向" />
        <xs:element ref="風速" />
      </xs:sequence>
      <xs:attribute name="日時" type="xs:dateTime" />
    </xs:complexType>
  </xs:element>

先の「気象計測」要素の定義の中で参照(ref)された「計測値」要素の宣言と型定義を記述します。ここでのsequenceの使い方は、先の意味とは異なり、記述した子要素(xs:elementの4つ)が順番に1つずつ必ず記述されるという意味になります。

各子要素は、先の記述スタイルによって、参照のみとし、それぞれの要素の定義はこの後ろに記述します。

属性は、attributeによって定義できます。

温度・湿度・風向・風速の定義を記述
  <xs:element name="温度" type="xs:decimal" />
  <xs:element name="湿度" type="xs:decimal" />
  <xs:element name="風向" type="xs:unsignedShort" />
  <xs:element name="風速" type="xs:unsignedByte" />

これらの要素は、子要素を持たないので、type属性に型を記述します。

今までの記述をまとめたweather.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <!-- <気象計測>要素を定義 -->
  <xs:element name="気象計測">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="計測値" minOccurs="0" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- <計測値>要素を定義 -->
  <xs:element name="計測値">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="温度" />
        <xs:element ref="湿度" />
        <xs:element ref="風向" />
        <xs:element ref="風速" />
      </xs:sequence>
      <xs:attribute name="日時" type="xs:dateTime" />
    </xs:complexType>
  </xs:element>


  <xs:element name="温度" type="xs:decimal" />
  <xs:element name="湿度" type="xs:decimal" />
  <xs:element name="風向" type="xs:unsignedShort" />
  <xs:element name="風速" type="xs:unsignedByte" />

</xs:schema>

XMLスキーマに基づくXMLデータ記述

<?xml version="1.0" encoding="UTF-8" ?>

<気象計測 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="weather1.xsd">
  <計測値 日時="2010-10-27T16:15:01+09:00">
    <温度>14.7</温度>
    <湿度>59.3</湿度>
    <風向>72</風向>
    <風速>2</風速>
  </計測値>
  <計測値 日時="2010-10-27T17:18:30+09:00">
    <温度>14.2</温度>
    <湿度>59.3</湿度>
    <風向>66</風向>
    <風速>2</風速>
  </計測値>
</気象計測>