XMLパーサでなくとも、やれることはやれる。
XML第3弾。DTDについて、前回は実体参照関係について、DocBookを例にこうなっていると書きましたが、そもそもプログラムから使うためのXMLを他のスキーマなりルールに則った形がとても面倒。あらかじめ申しておきますが、ここは1からスキーマを設計する事を説明しています。妥当性を検証するのは、何もXML自体を記述するためではありません。要するの構造を理解する上で、XSLTとアプリを組み合わせて他のアプリのインターフェイスにするということです。DTDは要素中心のXML仕様なら、W3CXMLSchemaの方は真価を発揮するのは、複合型をどう取り扱うかです。そういえば、このW3CXMLSchemaの組み込みの固有要素にallというのがありますが、http://www.horobi.com/xml/XMLSchemaDosAndDONTs.ja.htmlnの中に
基底型:
<xs:all>
<xs:element name="a" />
<xs:element name="b" />
<xs:element name="c" minOccurs="0" />
</xs:all>
制限による派生型:
<xs:all>
<xs:element name="b" />
<xs:element name="a" />
</xs:all>
という記述があり、後者は不正なのが「せっかく制限を正しく書いても」と書いてあったがこれは、仕様書にキチンと記載があります。xs:allは謂わばコンテナの親にあたるので、この要素には、例えるならminOccurs="1"という属性を子に与える制限を保っているので、必ずこの要素の内容は全て出現するのが、前提です。この要素の属性は、親に対して上書きなど出来ないので、これは定義そのものが間違っていますね。
こんなのもありました。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMSchema"
targetNamespace="http://example.com">
<!-- attribute whose name is foo -->
<xs:attribute name="foo" type="xs:float" />
<xs:element name="root">
<xs:complexType>
<xs:attribute ref="foo" />
</xs:complexType>
</xs:element>
</xs:schema>
ここでは名前空間をルート要素として属性を与えていること自体、誤りです。
名前空間にあるtargetNamespace="http://example.com"ですが、文中ではXML全体に属性を与えたいということの意味で書かれたのだと思いますが、スキーマ定義の中で名前無し複合型で属性が宣言してあります。
これでは、始めにxs:attribute ref="foo"が読み込まれてしまい、グローバルがそれを上書きするのでおかしな事になるでしょう。宣言にattributeFormDefalt=の記述が足らないと考えるのが妥当でしょう。
後述している記述もあまり管理しにくい構成だと思いますね。わざわざグループ化するメリットはないのではないでしょうか。根本的に要素に限って利用した方が効率的です。属性は制約を受けないので、根本的にいくらでも子にローカルで与えられますし、グローバルで管理できます。
ヘタな工夫をするくらいなら、XMLでの記述は管理を煩雑にするだけです。
パーサーとはXMLを操作したり、値を削除挿入したりなどをする際に、そのプログラムのもつクラスライブラリを取り込んだり、またそのプログラムを利用する方法の事ですが、それをを組み合わせたアプリの設計も効率の悪いものになるでしょう。
しかしながら、スキーマに対してのドキュメントは少ないですね。冗長で意味のない要素だらけのトコロからお目当ての要素を拾い出すくらいなら、目で見てすぐに内容が判る短い記述と、外部参照を多用し双方から値を抜き出す仕組みの方が、遙かに簡単で済むように思います。
仕様書をよく熟読し、概要はオライリー XML入門でも、かなり理解は出来ます。
とにかく煩雑に考えるより、構造に注視することが何より前述のような、一種の誤解は防げるでしょう。
基底型:
<xs:all>
<xs:element name="a" />
<xs:element name="b" />
<xs:element name="c" minOccurs="0" />
</xs:all>
制限による派生型:
<xs:all>
<xs:element name="b" />
<xs:element name="a" />
</xs:all>
という記述があり、後者は不正なのが「せっかく制限を正しく書いても」と書いてあったがこれは、仕様書にキチンと記載があります。xs:allは謂わばコンテナの親にあたるので、この要素には、例えるならminOccurs="1"という属性を子に与える制限を保っているので、必ずこの要素の内容は全て出現するのが、前提です。この要素の属性は、親に対して上書きなど出来ないので、これは定義そのものが間違っていますね。
こんなのもありました。
<xs:schema xmlns:xs="http://www.w3.org/2001/XMSchema"
targetNamespace="http://example.com">
<!-- attribute whose name is foo -->
<xs:attribute name="foo" type="xs:float" />
<xs:element name="root">
<xs:complexType>
<xs:attribute ref="foo" />
</xs:complexType>
</xs:element>
</xs:schema>
ここでは名前空間をルート要素として属性を与えていること自体、誤りです。
名前空間にあるtargetNamespace="http://example.com"ですが、文中ではXML全体に属性を与えたいということの意味で書かれたのだと思いますが、スキーマ定義の中で名前無し複合型で属性が宣言してあります。
これでは、始めにxs:attribute ref="foo"が読み込まれてしまい、グローバルがそれを上書きするのでおかしな事になるでしょう。宣言にattributeFormDefalt=の記述が足らないと考えるのが妥当でしょう。
後述している記述もあまり管理しにくい構成だと思いますね。わざわざグループ化するメリットはないのではないでしょうか。根本的に要素に限って利用した方が効率的です。属性は制約を受けないので、根本的にいくらでも子にローカルで与えられますし、グローバルで管理できます。
ヘタな工夫をするくらいなら、XMLでの記述は管理を煩雑にするだけです。
パーサーとはXMLを操作したり、値を削除挿入したりなどをする際に、そのプログラムのもつクラスライブラリを取り込んだり、またそのプログラムを利用する方法の事ですが、それをを組み合わせたアプリの設計も効率の悪いものになるでしょう。
しかしながら、スキーマに対してのドキュメントは少ないですね。冗長で意味のない要素だらけのトコロからお目当ての要素を拾い出すくらいなら、目で見てすぐに内容が判る短い記述と、外部参照を多用し双方から値を抜き出す仕組みの方が、遙かに簡単で済むように思います。
仕様書をよく熟読し、概要はオライリー XML入門でも、かなり理解は出来ます。
とにかく煩雑に考えるより、構造に注視することが何より前述のような、一種の誤解は防げるでしょう。
Powered by ScribeFire.
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home