ここ最近気になっていたのでちゃんと解消しておこう。基礎が出来てなきゃダメダメ。
まず重要なのは、属性にはデフォルトネームスペースが適用されないのにされると勘違いしていたこと。属性と要素では属する partition が違う。接頭辞がない属性がよくある (たとえば XHTML とか) せいで完全に勘違い。
同じように見える属性でも厳密には違う場合が存在する。見た目的には接頭辞がついている属性と、付いていない属性では差がある。
<f:foo xmlns:f="http://example.com/foo"> <f:far attr="ex"/> <b:baz xmlns:b="http://example.com/baz"> <b:bar f:attr="ex"/> </b:baz> </f:foo>
この例で attr="ex" と f:attr="ex" は属している名前空間は同じにも関わらず展開すると異なる。これも partition の違い。
partition には三つあって、一つは全ての要素が属するとこ。あとは属性の属する partition で、一つはグローバルな属性が属する (上の例では f:attr) とこ、もう一つは要素ごとの別々な属性が属する (上の例で attr) とこ。かなーりややこしい!
partition の種類は三つ。一つは要素が属する partition で、これは特に問題にならないでそのまんま。属性は残りの二つのどちらかに属するんだけどこれが面倒くさい。違いは名前空間にグローバルかローカルか。接頭辞をつける属性は名前空間にグローバル。接頭辞をつけない属性は要素名を経由する (ローカル)。たぶんこれは展開された名前とかを見るとわかりやすいと思う。
<f:far attr="ex"/>
の attr="ex"- {http://example.com/foo}far@attr
- f:far に属している attr という感じ。 far を経由して認識 (っていうのかな) される。
<b:bar f:attr="ex"/>
の f:attr="ex"- {http://example.com/foo}@attr
- b:bar は関係なく、名前空間 URI がそのまま属性の名前にくっつく
接頭辞をそのまま名前空間の URI に置き換える (ようは展開することなんだけど) だけでだいぶイメージしやすいと思う。
一般的な XML では (XHTML とかじゃなくて) 普通接頭辞をつけることになりそう? この辺わかってない。むしろ要素ごとに別々の意味をもつ要素を定義できるかっつうとできないような。
バカすぎるスペルミスを修正。
気になっていたことを一つ試したのでメモ。<f:foo f:attr="a1" attr="a2"/>
としたときエラーになるか、ということと、実際 XPath からはどちらにもアクセスできるのかということ。結果的にはエラーにならないし、XPath からはどちらにもアクセスできる。f:foo/@f:attr = 'a1'
, f:foo/@attr = 'a2'
XML Schema についてで なぜ属性宣言を避けるべきか ってのがあった。これは XML 名前空間の partition を理解していればひっかかりにくい (ひっかかっても直ぐに気付ける) とこだなぁ。