xsd:anyAttribute

2003年6月1日(日)更新


■XMLデータ例とXML Schema例

たけち: 前回は「任意のどんな要素が出現してもよい」というxsd:anyについて学んだね。「任意のどんな要素が出現してもよい」ということができるのだったら、「任意のどんな属性が出現してもよい」ということができてもいいよね。

さらら: えぇ、そうね。

たけち: というわけで、今回は「任意のどんな属性が出現してもよい」というxsd:anyAttributeについて勉強しようね。まずは次のXMLデータとXML Schemaの例を見て。

XMLデータ例: 【m_poem.xml】
<?xml version="1.0" encoding="Shift_JIS" ?>
<?xml-stylesheet type="text/xsl" href="print.xsl"?>
<mp:poem pno="4088" xmlns:mp="http://www.litera-ltd.jp/ns/manyoPoem"
     xmlns:print="http://www.litera-ltd.jp/ns/print"
     xsi:schemaLocation="http://www.litera-ltd.jp/ns/manyoPoem manyoPoem.xsd"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mp:poet print:color="black"><大伴家持</mp:poet>
<mp:kana print:color="red">左由理婆奈 由里毛安波牟等 於毛倍許曽 伊末能麻左可母 宇流波之美須礼</mp:kana>
<mp:yomi print:color="blue">さ百合花、ゆりも逢はむと、思へこそ、今のまさかも、うるはしみすれ</mp:yomi>
</mp:poem>

XML Schema例: 【manyoPoem.xsd】
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.litera-ltd.jp/ns/manyoPoem"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:mp="http://www.litera-ltd.jp/ns/manyoPoem"
     xmlns:print="http://www.litera-ltd.jp/ns/print">

<xsd:import namespace="http://www.litera-ltd.jp/ns/print"
     schemaLocation="print.xsd" />


<xsd:element name="poem" type="mp:PoemType" />

<xsd:complexType name="PoemType">
  <xsd:sequence>
    <xsd:element ref="mp:poet" />
    <xsd:element ref="mp:kana" />
    <xsd:element ref="mp:yomi" />
  </xsd:sequence>
  <xsd:attribute name="pno" type="xsd:positiveInteger" />
</xsd:complexType>

<xsd:element name="poet" type="mp:PoetType" />
<xsd:element name="kana" type="mp:KanaType" />
<xsd:element name="yomi" type="mp:YomiType" />

<xsd:complexType name="PoetType">
  <xsd:simpleContent>
    <xsd:extension base="xsd:string">
      <xsd:attribute ref="print:color" />
    </xsd:extension>
  </xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="KanaType">
  <xsd:simpleContent>
    <xsd:extension base="xsd:string">
      <xsd:attribute ref="print:color" />
    </xsd:extension>
  </xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="YomiType">
  <xsd:simpleContent>
    <xsd:extension base="xsd:string">
      <xsd:attribute ref="print:color" />
    </xsd:extension>
  </xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

XML Schema例: 【print.xsd】
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.litera-ltd.jp/ns/print"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:print="http://www.litera-ltd.jp/ns/print">

<xsd:attribute name="color" type="print:ColorType" />

<xsd:simpleType name="ColorType">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="black" />
    <xsd:enumeration value="white" />
    <xsd:enumeration value="blue" />
    <xsd:enumeration value="red" />
    <xsd:enumeration value="yellow" />
    <xsd:enumeration value="green" />
    <xsd:enumeration value="purple" />
  </xsd:restriction>
</xsd:simpleType>

</xsd:schema>


■グローバル属性の利用

さらら: これって以前、グローバル属性を勉強してきたときに出てきた例と同じだわよね。

たけち: そうだね。厳密に言うとXMLデータの中でxsi:schemaLocation属性を使っていることだけ違うけれど、中身は一緒だね。さて、ここでちょっと脱線するよ。このprint:color属性を使って、これを使っているどんなXMLデータでも、それなり表示させてしまうprint.xslというXSLTプログラムを示すね。

さらら: あら、XSLTなんて久しぶりね。(^ ^*/p>

XSLT例: 【print.xsl】
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:print="http://www.litera-ltd.jp/ns/print"
     xmlns="http://www.w3.org/1999/xhtml">
<xsl:template match="/">
<html>
<head>
<title>
print</title>
</head>
<body>
     <xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="*">
     <xsl:choose>
     <xsl:when test="@print:color">
         <font color="{@print:color}">
         <xsl:value-of select="local-name(.)" />
         <xsl:text>
:</xsl:text>
<br />
         <xsl:apply-templates />
         </font>
     </xsl:when>
     <xsl:otherwise>
         <xsl:value-of select="local-name(.)" />
    v     <xsl:text>
:</xsl:text>
<br />
         <xsl:apply-templates />
     </xsl:otherwise>
     </xsl:choose>
</xsl:template>
<xsl:template match="text()">
         <xsl:value-of select="." />
<br />
</xsl:template>
</xsl:stylesheet>

たけち: このXSLTを最初のXMLデータ【m_poem.xml】に適用すると、次のような表示(ここでは、IE 6.0の場合)がされるんだよ。一応、以上のファイルの関連も載せておくね。

【m_poem.xml】に【print.xsl】を適用した結果(IE 6.0の場合)

ファイルの関連

さらら: へぇ〜。

たけち: 簡単なXSLTの割には、まあまあの表示ができているように思えないかい。

さらら: まあ、そう言われればそうね。

たけち: それで、このprint:colorについてのXML Schema【print.xsd】とXSLT【print.xsl】とを見て欲しいんだけれど、このXML SchemaもXSLTも、どのようなXMLデータに対しても適用できるように作られているんだよね。つまり、print:colorというグローバル属性が、いかなる名前空間のスキーマのXMLデータに対して使われても、とにかくこのグローバル属性を使うだけで、それなりに表示させることができるんだ。これって凄いことだと思わないかい?

さらら: ふ〜ん。。

たけち: (さっ、さらら.....(^ ^;) ) 実は、グローバル属性を入れ込むだけで、これだけのことができてしまう、というのはとても便利なんだよ。というのは、元々意図したxmlns:mp="http://www.litera-ltd.jp/ns/manyouPoem"のようなXMLデータのツリー構造を改造しなくてもいいからね。

たけち

さらら: あら、でも、「ツリー構造を改造しなくてもいい」と言っても、さっきはしっかりimportでprint.xsdを取り込んで、そして各要素のデータ型定義の中で参照しないといけなかったじゃない。

たけち: 確かにそうだね。実際にシステムを運用する際には、本当にこういうprint:colorのようなグローバル属性が必要になってくるかどうかなんて、前もってわからないことがほとんどだよね。例えばprint:colorとはまた別の印刷に必要なグローバル属性が必要になってくるかもしれないしね。

さらら: えっ、えぇ。それはそうだわね。

たけち: そこで、大事になってくるのは、print:colorみたいな、グローバル属性だけでいろいろな仕事をしてくれるアプリケーションが使えるように、最初から「(任意の)どんな属性が出現してもよい」という設定を、すべての要素のデータ型の定義の中に仕込んでおくことなんだ。実際にそういうふうに改造した例を見てみようね。

たけち

■XMLデータ例とXML Schema例(xsd:anyAttributeを使用)

XMLデータ例: xsd:anyAttribute
<?xml version="1.0" encoding="Shfit_JIS" ?>
<?xml-stylesheet type="text/xsl" href="print.xsl"?>
<mp:poem pno="4088" xmlns:mp="http://www.litera-ltd.jp/ns/manyouPoem"
     xmlns:print="http://www.litera-ltd.jp/ns/print"
     xsi:schemaLocation="http://www.litera-ltd.jp/ns/manyouPoem   manyouPoem.xsd
           http://www.litera-ltd.jp/ns/print   print.xsd"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mp:poet print:color="black">
大伴家持</mp:poet>
<mp:kana print:color="red">
左由理婆奈 由里毛安波牟等 於毛倍許曽 伊末能麻左可母 宇流波之美須礼</mp:kana>
<mp:yomi print:color="blue">
さ百合花、ゆりも逢はむと、思へこそ、今のまさかも、うるはしみすれ</mp:yomi>
</mp:poem>

XML Schema例: 【manyouPoem.xsd】 xsd:anyAttribute
<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema targetNamespace="http://www.litera-ltd.jp/ns/manyouPoem"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:mp="http://www.litera-ltd.jp/ns/manyouPoem">

<xsd:element name="poem" type="mp:PoemType" />

<xsd:complexType name="PoemType">
    <xsd:sequence>
        <xsd:element ref="mp:poet" />
        <xsd:element ref="mp:kana" />
        <xsd:element ref="mp:yomi" />
    </xsd:sequence>
    <xsd:attribute name="pno" type="xsd:positiveInteger" />
    <xsd:anyAttribute namespace="##other" processContents="lax" />
</xsd:complexType>

<xsd:element name="poet" type="mp:PoetType" />
<xsd:element name="kana" type="mp:KanaType" />
<xsd:element name="yomi" type="mp:YomiType" />

<xsd:complexType name="PoetType">
    <xsd:simpleContent>
    <xsd:extension base="xsd:string">
            <xsd:anyAttribute namespace="##other" processContents="lax" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="KanaType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
            <xsd:anyAttribute namespace="##other" processContents="lax" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="YomiType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
            <xsd:anyAttribute namespace="##other" processContents="lax" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema>

さらら: あ、前回のxsd:anyにそっくりな、
            <xsd:anyAttribute namespace="##other" processContents="lax" />
 というのがあるわ。

たけち: そうだね。xsd:anyの部分がxsd:anyAttributeになった以外、まったく同じだよね。そして実際に、その中の属性の意味や使い方もまったく同じだよ。それから、xsi:schemaLocationの値も、
     xsi:schemaLocation="http://www.litera-ltd.jp/ns/manyouPoem   manyouPoem.xsd
           http://www.litera-ltd.jp/ns/print   print.xsd"

 というふうに2種類の名前空間とスキーマファイルのペアを指定している、ということにも気をつけてね。

さらら: えぇ。

たけち: 前回の復習みたいになってしまうけれど、再度まとめると、次のようになるんだ。

  • <xsd:anyAttribute namespace="##other" />
    対象名前空間以外の名前空間に属した属性が出現可能
  • <xsd:anyAttribute namesapce="##targetNamespace" />
    対象名前空間に属した属性が出現可能
  • <xsd:anyAttribute namespace="##any" />
    すべての任意の属性が出現可能(namespace属性が省略された場合、これがデフォルトとなる)
  • <xsd:anyAttribute namesapce="##local" />
    名前空間を持たない任意の属性が出現可能
  • <xsd:anyAttribute namesapce="http://example.com/ex1   http://example.com/ex2" />
    名前空間http://example.com/ex1と名前空間http://example.com/ex2の任意の要素が出現可能


■xsd:anyAttributeの注意事項

たけち: ##anyや##otherが他の設定と同時に使えないことも前回とxsd:anyと同じだね。processContents属性も同じだから、この説明についてはもう省略するね。

さらら: ほんと、そっくりねぇ。

たけち: ただし、xsd:anyと根本的に違うのは、出現制約に対する考え方なんだ。xsd:anyではminOccurs属性やmaxOccurs属性などを設定できたけれど、xsd:anyAttributeにはuse属性などは存在しないんだ。そしてnamesapce属性などの設定に従う限りは、複数のいろいろな種類の任意の属性が出現してもいいし、しなくてもいいわけなんだね。このあたりは、要素と属性の性質の違いが、こういう差を結果的に作り出したとも言えるね。

さらら: あ、そうかuse属性は使えないのね。...(^ ^;

たけち: そしてもう一つ、次を見て欲しいんだけど。

さらら

PoemType: xsd:anyAttributeを書く場所
<xsd:complexType name="PoemType">
    <xsd:sequence>
        <xsd:element ref="mp:poet" />
        <xsd:element ref="mp:kana" />
        <xsd:element ref="mp:yomi" />
    </xsd:sequence>
    <xsd:attribute name="pno" type="xsd:positiveInteger" />
    <xsd:anyAttribute namespace="##other" processContents="lax" />
</xsd:complexType>

たけち: 以前、複合型の定義の中では、内容モデルが最初に来て、その後にxsd:attributeやxsd:attributeGroupが来ないといけないという話をしたよね。
そして、xsd:anyAttributeを書いても良いのは、このxsd:attributeやxsd:attributeGroupよりも、さらにその後なんだ。つまり、複合型定義の中の一番最後に書かないといけないんだよ。

さらら: へぇ〜、こんなきまりがあるのね。

たけち: xsd:anyAttributeについてはこれでおしまい。次回はxsi:nilについて説明することにするね。

さらら: あっ、は〜い。ありがと。

次回はグローバル属性 - xsi:nil属性です...... (^ ^;

さらら

XMLスキーマのコーナーは、TAKABEさま(XSLTの遊び部屋)の全面的なご協力をいただいて作成しています。