- - PR -
子要素の宣言方法 ref属性とtype属性
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-11-29 11:52
XMLスキーマを勉強中です。
子要素の宣言方法ですが、 "ref属性"でするのか、"type属性"でするのか、迷っています。 基準、ないしは指針のようなものがありましたら、ご教授願います。 例えば、以下の2通りの宣言方法ができると思います。 (8行目の宣言とその関連の13行目以降が異なっています) 宣言方法1:"ref属性"での宣言 1:<?xml version="1.0"?> 2:<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 3: 4:<xsd:element name="customer"> 5:<xsd:complexType> 6: <xsd:sequence> 7: <xsd:element name="name" type="xsd:string"/> 8: <xsd:element ref="address"/> 9: </xsd:sequence> 10:</xsd:complexType> 11:</xsd:element> 12: 13:<xsd:element name="address"> 14:<xsd:complexType> 15:<xsd:sequence> 16:<xsd:element name="prefecture" type="xsd:string"/> 17:<xsd:element name="city" type="xsd:string" /> 18:<xsd:element name="street" type="xsd:string" /> 19:</xsd:sequence> 20:</xsd:complexType> 21:</xsd:element> 22: 23: </xsd:schema> 宣言方法2:"type属性"での宣言 1: <?xml version="1.0"?> 2: <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 3: 4: <xsd:element name="customer"> 5: <xsd:complexType> 6: <xsd:sequence> 7: <xsd:element name="name" type="xsd:string"/> 8: <xsd:element name="address" type="address_type"/> 9: </xsd:sequence> 10:</xsd:complexType> 11:</xsd:element> 12: 13:<xsd:complexType name="address_type"> 14:<xsd:sequence> 15:<xsd:element name="prefecture" type="xsd:string"/> 16:<xsd:element name="city" type="xsd:string" /> 17:<xsd:element name="street" type="xsd:string" /> 18:</xsd:sequence> 19:</xsd:complexType> 20: 21: </xsd:schema> type属性での宣言では、当然ながら、型を新規に追加宣言しなくては なりません。ref属性の場合はそういう必要がありません。 ただ、ref属性での宣言はあまり見かけませんが、何か理由があるので しょうか。 上記は以下の内容を参考にしています。 http://www.atmarkit.co.jp/fxml/rensai2/schema02/schema02.html http://www.atmarkit.co.jp/fxml/tecs/020xsd/20.html よろしくお願いします。 | ||||
|
投稿日時: 2004-11-29 14:35
豪雪地帯さま、こんにちは。
「要素をグローバルに宣言すべきか、ローカルに宣言すべきか」 という問題ですね。いろいろな考え方があると思いますが、ひとまず機能的に違いが出ることとして、 (1) この要素が本当に他の要素やデータ型から参照される可能性はないかどうか (2) 他の要素の子要素としてこの要素が出現する場合、親要素に応じてこの要素のデータ型を変更する必要性があるかどうか といったことなどがあげられるかと思います。 まず(1)ですが、ある要素がいろいろな要素(もしくはその宣言に使われるデータ型)の子要素として出現するような場合には((2)に示すような例外を省けば)、グローバルに要素を宣言しておいて、それを参照する方法が自然な書き方と言えるかもしれません(?)。それに対して、あるスキーマの中で、ある親要素の中だけにしか出現しない子要素は、グローバルに宣言してもローカルに宣言しても機能的な違いおきないはずです。(もちろん対象名前空間が設定されている場合でも、elementFormDefault="qualified"等を使って、同等になっているとしての話です) ただし、その場合でもちょっとした落とし穴に嵌る場合もあって、それは何かというと、後になってその要素を他のスキーマから参照したくなったような場合に違いが生じます。 他のスキーマからこのスキーマがインポートされた場合でも、その別のスキーマから直接参照できる要素は、グローバルに宣言された要素だけです。上記2つの例どちらでもcustomer要素はグローバルに宣言されていますから、他のスキーマからこれを参照することができます。ところが、「address要素は参照したいが、customer要素は参照しない」としたいようなケースが生じた場合には、上記2つの例では違いが生じます。customer要素の宣言の中(もしくはcustomer要素の宣言に使われるデータ型定義の中)でaddress要素がローカルに宣言されている場合は、customer要素の参照なしに(もしくはcustomer要素の宣言に使われるデータ型定義の参照なしに)address要素を使うことができません。これに対して、address要素がグローバルに宣言されている場合には、customer要素の必要性云々に関係なく、直接address要素を参照できます。 次に(2)ですが… 例えば、foo要素という別の要素の子要素としてもaddress要素が出現すると仮定します。address要素がグローバルに宣言され、それをcustomer要素やfoo要素が参照する場合は、その子要素として出現するaddress要素はどちらの親要素の中で出現しようとも、同じデータ型(address_type)です。ところが、customer要素とfoo要素それぞれの宣言の中(もしくはcustomer要素やfoo要素の宣言に使われるデータ型定義の中)でaddress要素をローカルに宣言した場合、customer要素の子要素となるaddress要素と、foo要素の子要素となるaddress要素では、それぞれ異なるデータ型を割り当てることが可能になります。つまり、customer要素の子要素となるaddress要素にはaddress_typeデータ型を割り当てるが、foo要素の子要素となるaddress要素にはxsd:string型を割り当てたりとかhoge型を割り当てる…といったことが、ローカルに宣言する場合には可能となります。 あくまで私個人の指針ですが、私の場合は、(2)のような親要素に応じてデータ型を変える同名の要素を宣言しないといけないようなケースを要求されない限りは、基本的に、要素はグローバルに宣言するようにしています。 まあいろいろな考え方があると思うのですが… [ メッセージ編集済み 編集者: TAKABE 編集日時 2004-11-29 17:25 ] | ||||
|
投稿日時: 2004-11-29 18:06
TAKABEさん、こんにちは。
グローバルな宣言と、ローカルな宣言というのを知らなかったので、TAKABEさんのコメントを読み返しながら、勉強しました。 そこで、まず確認ですが、 element要素がschema要素の直子供として現れる場合はグローバルな要素宣言であり、 complex要素の内容として現れる場合はローカルな要素宣言である。 と認識した(attribute要素もそう)のですが、合っていますか。 そうならば、それと質問の宣言を照らし合わせると、 宣言方法1(ref属性宣言)のcustomerとaddress要素はグローバルな要素宣言で、 宣言方法2(type属性宣言)ではcustomerのみがグローバルな要素宣言で、 address_typeは単に複合型の定義である(element要素でないのでローカルな要素宣言 とは違う)、 という事で合っているでしょうか。 で、それぞれのメリット・デメリットはTAKABEさんの(1)と(2)の通りですが、 TAKABEさんとしては、基本的には、宣言方法1(ref属性宣言)の方にするようにしている、 ということで間違いないでしょうか。 >あくまで私個人の指針ですが、私の場合は、(2)のような親要素に応じてデータ型を変える >同名の要素を宣言しないといけないようなケースを要求されない限りは、 >基本的にグローバルに宣言するようにしています。 私もTAKABEさんに従おうと思います。 [ メッセージ編集済み 編集者: 豪雪地帯 編集日時 2004-11-29 18:08 ] | ||||
|
投稿日時: 2004-11-30 10:27
豪雪地帯さん、こんにちは。
>そこで、まず確認ですが、 > element要素がschema要素の直子供として現れる場合はグローバルな要素宣言であり、 > complex要素の内容として現れる場合はローカルな要素宣言である。 >と認識した(attribute要素もそう)のですが、合っていますか。 : : >で、それぞれのメリット・デメリットはTAKABEさんの(1)と(2)の通りですが、 >TAKABEさんとしては、基本的には、宣言方法1(ref属性宣言)の方にするようにしている、 >ということで間違いないでしょうか。 はい、そうです。 >>同名の要素を宣言しないといけないようなケースを要求されない限りは、 >>基本的にグローバルに宣言するようにしています。 >私もTAKABEさんに従おうと思います。 まあ、これはあくまで色々な考え方がある中での「私流」の方法ですから、あくまで参考程度に考えてくださいませ(^^) 一応、W3Cによる要素のグローバルな宣言とローカルな宣言の極めて簡単な比較の解説が 「XML Schema Part 0: Primer Second Edition」 3.3 Global vs. Local Declarations http://www.w3.org/TR/xmlschema-0/#GlobalvsLocal にあります。 ちなみに私の場合、データ型の定義についても、一応「データ型の再利用性」の可能性ということを考えて、「匿名の型定義」は使わずに、きちんと名前を付けてデータ型を定義した書き方を基本にしています。(これまた色々と異論が噴出しそうなところではあるのですが(^^;) ) | ||||
|
投稿日時: 2004-11-30 11:02
こんにちは。
私も最近XMLスキーマを勉強し始めたのですが、
この落とし穴にはまった一人です。 他のあるXMLスキーマから一部の要素を利用しようと思っていたのですが、 グローバルに宣言されていない要素だったため、不可能であるということに 最近気づきました。^^; | ||||
|
投稿日時: 2004-11-30 11:25
めぐさま、こんにちは。
>この落とし穴にはまった一人です。 やはり、はまった方がおられたのですね 再利用したい場合というのは、後になってから出てくることがやっぱりありますね どういうXML Schemaの書き方が理想的なのかというのは、いろいろと議論が分かれるところかと思うのですが、私が影響を受けたのは、W3Cの Modularization of XHTML 1.0 - Second Edition http://www.w3.org/TR/2004/WD-xhtml-modularization-20040218/ によるところが大きいです。 ここに出てくる書き方や考え方はとても勉強になりました。 [ メッセージ編集済み 編集者: TAKABE 編集日時 2004-11-30 12:34 ] |
1