Step48 xsd:anyAttribute たけち: 前回は「任意のどんな要素が出現してもよい」というxsd:anyについて学んだけれど、「任意のどんな要素が出現してもよい」ということができるのだったら、同様に「任意のどんな属性が出現してもよい」ということができてもいいよね。 さらら: それは、そうだわ。 たけち: というわけで、今回は「任意のどんな属性が出現してもよい」というxsd:anyAttributeについて勉強しようね。まずは次のXMLデータとXML Schemaの例を見てみてね。 大伴家持 左由理婆奈 由里毛安波牟等 於毛倍許曽 伊末能麻左可母 宇流波之美須礼 さ百合花、ゆりも逢はむと、思へこそ、今のまさかも、うるはしみすれ -------------------------------------------------- 【manyouPoem1.xsd】 -------------------------------------------------- 【print.xsd】 -------------------------------------------------- さらら: これって以前、グローバル属性を勉強してきたときに出てきた例と同じだわ。 たけち: そうだね。厳密に言うとXMLデータの中でxsi:schemaLocation属性を使っていることだけ違うけれど、中身は一緒だね。さて、ここでちょっと脱線するよ。このprint:color属性を使って、これを使っているどんなXMLデータでも、それなり表示させてしまうprint.xslというXSLTプログラムを示すね。 【print.xsl】 print :
:

 このXSLTを最初のXMLデータに適用すると、 poem : poet : 大伴家持 kana : 左由理婆奈 由里毛安波牟等 於毛倍許曽 伊末能麻左可母 宇流波之美須礼 yomi : さ百合花、ゆりも逢はむと、思へこそ、今のまさかも、うるはしみすれ  という感じで表示されるんだ。簡単なXSLTの割には、まあまあの表示ができているように思えないかい。 さらら: まあ、そう言われればそうね。 たけち: それで、このprint:colorについてのXML Schema「print.xsd」とXSLT「print.xsl」とを見て欲しいんだけれど、このXML SchemaもXSLTも、どのようなXMLデータに対しても適用できるように作られているんだよね。つまり、print:colorというグローバル属性が、いかなる名前空間のスキーマのXMLデータに対して使われても、とにかくこのグローバル属性を使うだけで、それなりに表示させることができるんだ。これって凄いことだと思わないかい? さらら: ふーん。 たけち: (がくっ(^^;) ) 実は、グローバル属性を入れ込むだけで、これだけのことができてしまう、というのはとても便利なんだよ。というのは、元々意図したxmlns:mp="http://www.yuragi.jp/ns/manyouPoem"のようなXMLデータのツリー構造を改造しなくてもいいからね。 さらら: あら、でも、「ツリー構造を改造しなくてもいい」と言っても、さっきはしっかりimportでprint.xsdを取り込んで、そして各要素のデータ型定義の中で参照しないといけなかったじゃない。 たけち: 確かにそうだね。実際にシステムを運用する際には、本当にこういうprint:colorのようなグローバル属性が必要になってくるかどうかなんて、前もってわからないことがほとんどだよね。例えばprint:colorとはまた別の印刷に必要なグローバル属性が必要になってくるかもしれないしね。 さらら: うーん、それはそうだわね。 たけち: そこで、大事になってくるのは、print:colorみたいな、グローバル属性だけでいろいろな仕事をしてくれるアプリケーションが使えるように、最初から「任意のどんな属性が出現してもよい」という設定を、すべての要素のデータ型の定義の中に仕込んでおくことなんだ。実際にそういうふうに改造した例を見てみようね。 大伴家持 左由理婆奈 由里毛安波牟等 於毛倍許曽 伊末能麻左可母 宇流波之美須礼 さ百合花、ゆりも逢はむと、思へこそ、今のまさかも、うるはしみすれ -------------------------------------------------- 【manyouPoem.xsd】 さらら: あ、前回のxsd:anyにそっくりな、  というのがあるわ。 たけち: そうだね。xsd:anyの部分がxsd:anyAttributeになった以外、まったく同じだよね。そして実際に、その中の属性の意味や使い方もまったく同じだよ。それから、xsi:schemaLocationの値も、 xsi:schemaLocation="http://www.yuragi.jp/ns/manyouPoem manyouPoem.xsd http://www.yuragi.jp/ns/print print.xsd"  というふうに2種類の名前空間とスキーマファイルのペアを指定している、ということにも気をつけてね。まず、前回の復習みたいになってしまうけれど、再度まとめると、 対象名前空間以外の名前空間に属した属性が出現可能 対象名前空間に属した属性が出現可能 すべての任意の属性が出現可能 (namespace属性が省略された場合、これがデフォルトとなる) 名前空間を持たない任意の属性が出現可能 名前空間http://example.com/ex1と名前空間http://example.com/ex2の任意の属性が出現可能  という形になるんだ。そして##anyや##otherが他の設定と同時に使えないことも前回とxsd:anyと同じだね。processContents属性も同じだから、この説明についてはもう省略するね。 さらら: ふーん、そっくりねぇ。 たけち: ただし、xsd:anyと根本的に違うのは、出現制約に対する考え方なんだ。xsd:anyではminOccurs属性やmaxOccurs属性などを設定できたけれど、xsd:anyAttributeにはuse属性などは存在しないんだ。そしてnamesapce属性などの設定に従う限りは、複数のいろいろな種類の任意の属性が出現してもいいし、しなくてもいいわけなんだね。このあたりは、要素と属性の性質の違いが、こういう差を結果的に作り出したとも言えるね。 さらら: あ、そうかuse属性は使えないのね。 たけち: そしてもう一つ、気をつけて欲しいのは、  のところを特に見て欲しいんだけれど、以前、複合型の定義の中では、内容モデルが最初に来て、その後にが来ないといけないという話をしたよね。そして、を書いても良いのは、このよりも、さらにその後なんだ。つまり、複合型定義の中の一番最後に書かないといけないんだよ。 さらら: へぇ、そんな決まりがあるのね。 たけち: xsd:anyAttributeについてはこれでおしまい。次回はxsi:nilについて説明することにするね。