とりあえずXMLデータバインディングに必要な知識をまとめてみました。
とりあえずXMLSpyで、XMLから生成してみます。
生成元XML: example.xml 01 <?xml version="1.0" encoding="UTF-8"?> 02 <employee> 03 <name></name> 04 <id></id> 05 <telephone> 06 <cell></cell> 07 <office></office> 08 </telephone> 09 </employee>
生成されたXSD: example.xsd 01 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 02 <!--W3C Schema generated by XMLSpy v2005 sp1 U (http://www.xmlspy.com)--> 03 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> 04 <xs:element name="employee"> 05 <xs:complexType> 06 <xs:sequence> 07 <xs:element name="name" type="xs:string"/> 08 <xs:element name="id" type="xs:string"/> 09 <xs:element name="telephone"> 10 <xs:complexType> 11 <xs:sequence> 12 <xs:element name="cell" type="xs:string"/> 13 <xs:element name="office" type="xs:string"/> 14 </xs:sequence> 15 </xs:complexType> 16 </xs:element> 17 </xs:sequence> 18 </xs:complexType> 19 </xs:element> 20 </xs:schema>
立派立派、プログラムに食べさせるには十分そうです。
生成オプションは
#ref(): File not found: "XMLSpyParam.png" at page "XML XMLSchema"
ミソは、Element which were used onceで、Make local definitionにすることです。
こうしないと入れ子になっているところは別のタグ定義になってしまう。(XMLのValidationと言う観点では問題ないけど、これからWSDLなりJavaBean?を生成すると、いらない細かいクラスがたくさんできることになる)
生成されたものくらい一通り理解しておきます
01 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
03 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> … 20 </xs:schema>
04 <xs:element name="employee"> … 19 </xs:element>
05 <xs:complexType> … 18 </xs:complexType>
06 <xs:sequence> … 17 </xs:sequence>
07 <xs:element name="name" type="xs:string"/> 08 <xs:element name="id" type="xs:string"/>
09 <xs:element name="telephone"> 10 <xs:complexType> 11 <xs:sequence> 12 <xs:element name="cell" type="xs:string"/> 13 <xs:element name="office" type="xs:string"/> 14 </xs:sequence> 15 </xs:complexType> 16 </xs:element>
xs:string | 文字列 |
xs:boolean | 真偽値(true/false/1/0) |
xs:byte | 符号付き1バイト整数(-128〜127) |
xs:short | 符号付き2バイト整数(-32768〜32767) |
xs:int | 符号付き4バイト整数(-2147483648〜2147483647) |
xs:long | 符号付き8バイト整数(-9223372036854775808〜9223372036854775807) |
xs:unsignedByte | 符号無し1バイト整数(0〜255) |
xs:unsignedShort | 符号無し2バイト整数(0〜65535) |
xs:unsignedInt | 符号無し4バイト整数(0〜4294967295) |
xs:unsignedlong | 符号無し8バイト整数(0〜18446744073709551615) |
xs:integer | 整数 |
xs:positiveInteger | 正の整数(1以上) |
xs:negativeInteger | 負の整数(0未満) |
xs:nonPositiveInteger? | 非正の整数(1未満) |
xs:nonNegativeInteger? | 非負の整数(0以上) |
xs:float | 単制度32bit浮動小数 |
xs:double | 倍制度64bit浮動小数 |
xs:base64Binary | バイナリデータ(Base64でエンコード) |
xs:hexBinary | バイナリデータ(16進表記 [0-9a-fA-F]*) |
xs:duration | 期間( P1Y2M3DT4H5M6.7S = 1年2ヶ月3日4時間5分6.7秒間) |
xs:dateTime | 日付時刻( CCYY-MM-DDThh:mm:ss.sss±hh:mm 2001-01-01T01:01:01.001+9:00) |
xs:date | 日付( CCYY-MM-DD±hh:mm ) |
xs:time | 時刻( hh:mm:ss.sss±hh:mm) |
xs:anyURI | URI形式の文字列( ldap://foo.com:386/ ) |
他に、[年]・[月]・[年月]・[日]・[改行文字]などがあるが、使わないので省略。
employee.xml <?xml version="1.0" encoding="UTF-8"?> <employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./example.xsd"> <name/> <id/> <telephone> <cell/> <office/> </telephone> </employee>
employee2.xml <?xml version="1.0" encoding="UTF-8"?> <employee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:employee="http://www.foo.com/employee" xsi:SchemaLocation="http://www.foo.com/employee ./example.xsd"> <employee:name/> <employee:id/> <employee:telephone> <employee:cell/> <employee:office/> </employee:telephone> </employee>
<xs:sequence>の他にも以下の存在条件指定ができます。
<xs:element ref="要素名" minOccurs="最低出現回数" maxOccurs="最大出現回数"/> minOccurs に、"0"を指定すると無くても良い要素になる maxOccurs に、"unbounded"を指定すると無制限になる
<xs:sequence minOccurs="最低出現回数" maxOccurs="最大出現回数"> </xs:sequence>
<xs:choice minOccurs="最低出現回数" maxOccurs="最大出現回数"> <xs:element name="str1" type="xs:string"/> <xs:element name="str2" type="xs:string"/> </xs:choice>
<xs:all minOccurs="最低出現回数" maxOccurs="最大出現回数"> <xs:element name="str1" type="xs:string"/> <xs:element name="str2" type="xs:string"/> </xs:all>
<xs:any namespace="****" processContents="****" minOccurs="最低出現回数" maxOccurs="最大出現回数"/> ここに出現した要素に対して: namespace ##any 全ての名前空間から要素定義を検索(デフォルト) ##other このSchema以外から要素定義を検索 ##targetNamespace このSchemaから要素定義を検索 ##local local要素をこの場で新たに作成 processContents strict 名前空間から要素定義を検索して検証する(デフォルト) lax 名前空間から要素定義を検索して見つかれば検証する skip 検証しない
グループ定義: <xs:group name="グループ名"> </xs:group>
グループ参照: <xs:group ref="グループ名" minOccurs="最低出現回数" maxOccurs="最大出現回数"/>
<?xml version="1.0" encoding="UTF-8"?> <body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="bodydef.xsd"> <name>Foo Bar</name> <length unit="m">1.70</length> <weight unit="kg" scale="1000">1.53</weight> </body>
<xs:element name="length" type="LengthType"/> <xs:complexType name="LengthType"> <xs:simpleContent> <xs:extension base="xs:double"> <xs:attribute name="unit" type="xs:string" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType>
use="required" | 必須 |
use="optional" | 任意 |
use="prohibit" | 使用不可 |
<xs:element name="length" type="LengthType"/> <xs:complexType name="LengthType"> <xs:simpleContent> <xs:extension base="xs:double"> <xs:attribute name="unit" type="LengthType" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="LengthUnitType"> <xs:restriction base="xs:string"> <xs:enumeration value="m"/> <xs:enumeration value="ft"/> </xs:restriction> </xs:simpleType>
<xs:complexType name="WeightType"> <xs:simpleContent> <xs:extension base="xs:double"> <xs:attribute name="unit" type="WeightUnitType" use="required"/> <xs:attribute name="scale" type="xs:positiveInteger" use="optional" /> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="WeightUnitType"> <xs:restriction base="xs:string"> <xs:enumeration value="kg"/> <xs:enumeration value="lbs"/> </xs:restriction> </xs:simpleType>
bodydef.xsd <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:include schemaLocation="unit_typedef.xsd"/> <xs:element name="body"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="length" type="LengthType"/> <xs:element name="weight" type="WeightType"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
unit_typedef.xsd <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:complexType name="LengthType"> <xs:simpleContent> <xs:extension base="xs:double"> <xs:attribute name="unit" type="LengthUnitType" use="required"/> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="LengthUnitType"> <xs:restriction base="xs:string"> <xs:enumeration value="m"/> <xs:enumeration value="ft"/> </xs:restriction> </xs:simpleType> <xs:complexType name="WeightType"> <xs:simpleContent> <xs:extension base="xs:double"> <xs:attribute name="unit" type="WeightUnitType" use="required"/> <xs:attribute name="scale" type="xs:positiveInteger" use="optional" /> </xs:extension> </xs:simpleContent> </xs:complexType> <xs:simpleType name="WeightUnitType"> <xs:restriction base="xs:string"> <xs:enumeration value="kg"/> <xs:enumeration value="lbs"/> </xs:restriction> </xs:simpleType> </xs:schema>