[ Home on 246ne ] [ XXXへ ]
TAKAHASHI, Toru 2010年10月27日着手
| JavaプログラムでXMLを扱う場合に、XMLの定義、プログラムとのやり取り、XMLデータの作成についての一例をまとめる。 | ||
プログラムをまたがったり、人間がデータを作成しプログラムに入れる、あるいはその逆を行うときに、XMLを使うのが一つの方向性となっており、JavaにはXMLを扱うための数多くの機能(ライブラリ)が備わっています。
そこで、プログラムの設計上、XML構造の定義をする必要があります。
XML構造の定義には、検証可能で、かつプログラムの自動生成が見込まれるスキーマ定義を活用するのが便利です。スキーマには過去いろいろないきさつがありましたが、現時点ではXML Schemaを使うのが汎用性が高いです。
ここでは、XMLのデータ構造として以下のような階層を持つものを例題とします。
◇気象計測
|
+---*◇計測値
+--- □日時 年月日時分秒を表す
+--- ◇温度 摂氏を10進小数で表す
+--- ◇湿度 %を10進小数で表す
+--- ◇風向 北を0度として時計回りを正とする角度で表す
+--- ◇風速 mで10進整数で表す
凡例:◇ 要素
□ 属性
* 複数(1:多)
XMLデータのイメージは以下です。
<気象計測>
<計測値 日時="XXXX">
<温度>XX.X</温度>
<湿度>XX.X</湿度>
<風向>XXX</風向>
<風速>X</風速>
</計測値>
:
</気象計測>
XMLスキーマの定義をしていきます。なお、名前空間を使った本格的な設計はいずれすることとし、ここでは名前空間を指定しない記述をします。
まずは、好みのエディタで、XMLスキーマを記述するため新規ファイルを開きます。ファイル名は、weather.xsdとします。
XML Schemaを使った記述もXMLなので、最初にXML宣言を記述します。
<?xml version="1.0" encoding="UTF-8"?>
ファイルの文字コードはUTF-8で作成することにしたので、encodingにUTF-8を指定しました。
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属性に型を記述します。
<?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 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</風速>
</計測値>
</気象計測>