名前空間が XML でどのように機能するかを理解しようとしています。foo:bar のような要素がある場合、属性に名前空間がないことがよくあります。しかし、時にはそうするでしょう。デフォルトの名前空間が宣言されている場合でも、属性は要素の名前空間にありますか? xhtmlのxsdを見ると、属性はスキーマの一部であり、xhtmlの名前空間にあるはずですが、そのように表示されることはありません...
4 に答える
ほとんどの場合、属性はどのネームスペースにもありません。名前空間の仕様には次のように書かれています(強調鉱山):
デフォルトの名前空間宣言は、そのスコープ内の接頭辞のないすべての要素名に適用されます。デフォルトの名前空間宣言は属性名に直接適用されません。接頭辞のない属性の解釈は、それらが現れる要素によって決定されます。
ほとんどの XML ボキャブラリが名前空間のない属性を使用するのには理由があり
ます。要素に名前空間があり、それらの要素に属性がある場合、混乱することはありません。属性は、名前空間に属する要素に属します。属性に名前空間プレフィックスを追加すると、すべてがより冗長になります。
では、なぜ名前空間属性が存在するのでしょうか?
一部の語彙は、ほとんどの属性で有用な作業を行い、他の語彙と混合するとこれを行うことができるためです。最もよく知られている例はXLinkです。
最後に、W3C XML Schema には、属性が名前空間にあると宣言する非常に簡単な方法 ( ) があり、デフォルトの名前空間を使用している場合でも<schema attributeFormDefault="qualified">
、ドキュメント内で属性を接頭辞にする必要があります。
クラーク表記の使用を説明する例。名前空間プレフィックスは中括弧で囲まれた名前空間URLに置き換えられます。
<bar xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/>
<bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/>
<foo:bar xmlns="http://www.foo.com/" xmlns:foo="http://www.foo.com/"
foo:baz="baz"
qux="qux"/>
は
<{}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/>
<{http://www.foo.com/}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/>
<{http://www.foo.com/}bar
{http://www.foo.com/}baz="baz"
{}qux="qux"/>
この属性/名前空間の件名に関連して、今日 XSD に取り組んでいたときに理解するのに時間がかかったことがあります。誰かが同じ問題を抱えている場合に備えて、この経験をあなたと共有します。
私が取り組んでいたスキーマ ドキュメントには、いくつかの要素によって参照されるグローバル属性がいくつかありました。ここで簡単にするために、私が話しているこの XSD がCustomerに関するものであると仮定しましょう。
これらのグローバル属性の 1 つをIdと呼びましょう。そして、それを使用するルート要素Customer
私のXSD宣言は次のようになりました:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://schemas.mycompany.com/Customer/V1"
targetNamespace="http://schemas.mycompany.com/Customer/V1"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
私のId属性宣言は次のようになりました。
<xs:attribute name="Id" type="xs:positiveInteger"/>
そして、私のCustomer要素は次のような属性を使用しました:
<xs:element name="Customer">
<xs:complexType>
<xs:attribute ref="Id" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
ここで、次のようなCustomer XML ドキュメントを宣言したいとします。
<?xml version="1.0" encoding="utf-8"?>
<Customer Id="1" xmlns="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
できないことがわかりました。属性がグローバルに宣言されている場合、それを参照する要素と同じ名前空間にありません。
そのように定義された XSD を使用した唯一の解決策は、名前空間を 2 回宣言することであることがわかりました。1 回目は要素のデフォルトの名前空間にするためにプレフィックスなしで、もう 1 回は属性で使用するためにプレフィックス付きです。したがって、これは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<Customer cus:Id="1" xmlns="http://schemas.mycompany.com/Customer/V1"
xmlns:cus="http://schemas.mycompany.com/Customer/V1">
<!-- ... other elements here -->
</Customer>
これは非常に非現実的であるため、すべてのグローバル属性を取り除き、それらをローカルで宣言することにしました。ここで示した例の場合、次のようになります。
<xs:element name="Customer">
<xs:complexType>
<xs:attribute name="Id" type="xs:positiveInteger" use="required"/>
<!-- some elements here -->
</xs:complexType>
</xs:element>
私がここで話していることについての参考文献をネットで見つけるのは難しいと思いました。最終的に、Stylus XSD フォーラムでこの投稿を見つけました。そこでは、Steen Lehmann という名前の男が、属性をローカルで宣言するか、属性グループ内で宣言することを提案しました。
「属性宣言自体がグローバルではなくなるように」
この最後の解決策は「ハッキー」な趣があるため、最初の解決策に固執し、すべての属性をローカルで宣言することにしました。
w3cの6.1名前空間スコープと6.2名前空間デフォルトを読んでください。
基本的に:
プレフィックスを宣言する名前空間宣言のスコープは、プレフィックスが表示される開始タグの先頭から、対応する終了タグの末尾まで拡張されます。
ただし、ここでのテキストは、aがfoo:aであるか、コンテキスト内のデフォルトの名前空間であるかを説明していないようです。foo:aを参照しているのではなく、ドキュメントのデフォルトの名前空間aを参照していると思います。少なくともこの引用を考慮すると:
このような名前空間宣言は、プレフィックスが宣言で指定されたものと一致するスコープ内のすべての要素名と属性名に適用されます。
つまり。名前空間「foo:」は、接頭辞foo:が付いた要素にのみ適用されます。