[ 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</風速> </計測値> </気象計測>