Unique Particle Attribution

ひさびさに WXS でハマったので、まとめておこうと思う。

WXS (W3C XML Schema) に UPA (Unique Particle Attribution) という制限がある。簡単にいってしまうと曖昧な内容モデルを排除するための規定である。たとえば


  
  

はこのコンテキストで、ある "a" 要素が出現したときに、どちらの a 要素か決定できないのでこのスキーマは valid でないということだ。上記では曖昧な内容モデルと書いたが、これは SGML 用語である。
XML 1.0 では非決定的内容モデルという。

XML 1.0 でこれは SGML との互換性のために用意されている。また DTD と組み合わせたときに発生する制限であり、整形式の XML 文書には関係がない。WXS では DTD のこれを踏襲して、見方によっては制限を加えて、UPA で非決定的内容モデルを禁止している。

一方で RELAX NG は非決定的内容モデルを許容する。たとえば以下のようなスキーマRELAX NG では許容されるが、WXS では UPA エラーとなる。

element a {
   element b { text }?,
   element * { text }*
}

ためしに、上記のスキーマを trang で rnc から xsd に変換してみた。結果は以下のとおりである。


  
    
      
        
        
      
    
  
  

これは UPA 違反になる。JAXB RI のスキーマコンパイラでは以下のようなエラーが出された。

% xjc test.xsd
parsing a schema...
[ERROR] cos-nonambig: "":b and WC[##any] (or elements from their
substitution group) violate "Unique Particle Attribution". During
validation against this schema, ambiguity would be created for
those two particles.
  line 4 of test.xsd

Failed to parse a schema.

これはなかなか困ったことだと思う。特にバージョンアップを見越して、最初から追加要素を許容するように xs:any (ワイルドカード)を使ったスキーマを書きたいケースはいくらでもあるだろう。

David Bau 氏の blog にもろこのことが書いてあった(というかあちらのページの方がこの日記よりも100倍わかりやすい)。いわく、ワイルドカードはバージョンアップを考えたスキーマ設計において非常に便利だけど UPA があって一筋縄ではいかない、ということだ。一つの解として extensions 要素を用意する、という方法が紹介されているがいくらなんでもこれは格好悪い。

XML のバージョニングについては、上記の Bau 氏の blog からリンクされているこの文書が役に立ちそうだ。ざっと見たけどこの絵なんかおもしろい。スキーマインスタンスの間に関連がないのもいけてる感じだ。

ちなみに非決定的内容モデルUPA まわりで苦労されている方の文書があった。ご苦労さまですとしか言いようがない。


追記(2004-06-26)
xjc には -nv というオプションがあり、これを使うと UPA を無視してくれる。さすがである。