web-dev-qa-db-ja.com

なぜtargetNamespaceが必要なのですか?

XMLスキーマとWSDLの両方で使用されるtargetNamespaceの目的を理解したいと思います。実際、物事を単純にするために、この質問をXMLスキーマに限定しましょう。

(単純な)XML名前空間の概念を完全に理解しているように感じます。慣例により、URI/URLを使用しますが、XMLノードおよび属性による再利用のためにプレフィックスに割り当てる任意の文字列を使用することも、単にスコープのデフォルト名前空間として使用することもできます。ここまでは順調ですね ?

XMLスキーマに入ります。何らかの理由で、XML Schemaの発明者は、単純な名前空間の概念だけでは不十分であり、targetNamespaceを導入する必要があると感じました。私の質問は、通常のXML名前空間では提供できなかったtargetNamespaceがもたらす重要な利点は何ですか? schemaLocationまたはimportステートメントによってXMLドキュメントがxsdドキュメントを参照する場合、どちらの場合でも、参照される実際のxsdドキュメントへのパスを指定します。これは、参照したいスキーマを一意に定義するものです。さらに、このスキーマを参照ドキュメントの特定の名前空間にバインドする場合、参照しているXMLスキーマで既に定義されている正確なtargetNamespaceを複製する必要があるのはなぜですか?この名前空間を単純に再定義できなかったのに、参照したい特定のXMLスキーマ文書を参照するためにこの名前空間が使用されるXML文書内で必要なのはなぜですか?

更新:

例として、XMLインスタンスドキュメントに次のものがある場合:

<p:Person
   xmlns:p="http://contoso.com/People"
   xmlns:v="http://contoso.com/Vehicles"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=
    "http://contoso.com/schemas/Vehicles
     http://contoso.com/schemas/vehicles.xsd
     http://contoso.com/schemas/People
     http://contoso.com/schemas/people.xsd">
   <name>John</name>
   <age>28</age>
   <height>59</height>
   <v:Vehicle>
      <color>Red</color>
      <wheels>4</wheels>
      <seats>2</seats>
   </v:Vehicle>
</p:Person>

なぜpeople.xsdスキーマは、「http://contoso.com/schemas/People」であるtargetNamespaceを定義する必要がありますか?なぜxsdドキュメントにtargetNamespace定義が必要なのですか? schemaLocationの名前空間部分がXMLインスタンスドキュメントに既に含まれていることから得なければならないことは私には思えます。 xsdドキュメントで等しい値を持つtargetNamespaceの存在を強制する利点は何ですか?

ポールの回答への追加質問:

Xsd要素名間のこのような「衝突」が明らかになり、targetNamespaceの必要性を説明する具体的な例を教えてください。


わかりました、私自身の質問に答える試みはここにあります。それがあなたにとって首尾一貫しているように見えるかどうか私に知らせてください。ポールがリンクしているページの例を見ると助けになりました。

上記の元の質問のXMLインスタンスの例を取り上げると、vehicle要素の定義への2つの参照があります。 1つはXMLインスタンスドキュメント自体で明示的かつ可視ですが、person.xsd XMLスキーマが再びpersonの許可された子要素として同じビークル定義を参照することを想像する必要があります。各ドキュメントが車両用の独自の名前空間を定義できる通常の名前空間を使用する場合、XMLインスタンスがperson.xsdと同じ車両用のXMLスキーマ定義を参照していることをどのようにして知ることができますか?唯一の方法は、元の単純な名前空間よりも厳密で、複数のドキュメント間でまったく同じ方法で記述しなければならない名前空間の概念を実施することです。

タブレットでこれを書いていなかった場合、コード例を提供しますが、ここでは念頭に置いた例を説明しようとします。

Vehicle要素に2つの異なるXMLスキーマ定義があるとします。 location1/vehicles.xsdには、この投稿の質問からの例を検証する定義(色、車輪、座席の子要素を含む)が含まれますが、location2/vehicles.xsdには、車両要素のまったく異なる定義が含まれます(たとえば、子要素年、モデル、およびボリュームを含む)。ここで、上記の例のようにXMLインスタンスドキュメントがlocation1スキーマを参照しているが、person.xsdがperson要素にlocation2スキーマで定義されたタイプの車両の子要素を含めることができると言っている場合、概念はありませんtargetNamespaceの場合、XMLインスタンスは、そのperson要素の子要素として適切な種類の媒体を明確に持たない場合でも検証します。

ターゲット名前空間は、2つの異なるドキュメントが同じ3番目のXMLスキーマを参照している場合、それらが両方とも同じスキーマを参照していること、および類似しているが互いに同一ではない要素を含むスキーマだけではないことを確認するのに役立ちます。 。

それは理にかなっていますか?

50
Student

あなたは正しい軌道に乗っているようです。ここで、役に立つかもしれないいくつかのポイントを作成します。

  • インスタンスドキュメント内で、XML名前空間を使用して、要素または属性が含まれる名前空間を識別します。
  • スキーマドキュメント内で、インスタンスに表示される要素と属性を宣言します。どの名前空間にあると宣言されていますか?これがtargetNamespaceの目的です。
  • スキーマドキュメントの場所と名前空間は同じものではありません。同じtargetNamespaceを持つ複数の.xsdドキュメントを持つことは非常に一般的です。 (それらはお互いを含む場合と含まない場合がありますが、通常はお互いを含みます。)
  • インスタンスドキュメントには、パーサーにスキーマの場所を知らせるxsi:schemaLocation要素が常にあるとは限りません。関連するスキーマドキュメントの場所をパーサーに伝えるために、さまざまな方法を使用できます。 XSDはローカルディスクまたはWebアドレスに配置できますが、これはその中の要素の名前空間に影響を与えません。
    • xsi:schemaLocationはヒントです。パーサーは、指定されたネームスペースのスキーマを他の場所に配置する場合があります。これは、スキーマがどのネームスペースのためのものかを知る必要があることを意味します。
    • データバインディングツールなどのツールは、スキーマをプリコンパイルし、有効なドキュメントを認識するコードを生成します。これらは宣言された要素の名前空間を知ることができなければなりません。

インスタンスドキュメントは、xsi:schemaLocationを使用して、スキーマドキュメントで宣言された要素と属性の名前空間を指定できると思います。それは機能しません。ひとつには、パーサーはリストされているもの以外のスキーマ文書を見つけることがあり、それが何の名前空間であるかを知る必要があります。もう1つは、スキーマについての推論を困難または不可能にすることです。インスタンスを作成するまでその決定は延期されるため、スキーマを見て、すべてが属している名前空間を知ることはできません。

17
Kevin

Q:「慣例により、URI/URLを使用しますが、任意の文字列を使用し、XMLノードと属性で再利用するためにプレフィックスに割り当てるか、単に手元のスコープのデフォルト名前空間として使用します。」

A:はい、正確に。

Q:「何らかの理由で、XML Schemaの発明者は、単純な名前空間の概念だけでは不十分であり、targetNamespaceを導入しなければならないと感じました。」

A: http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx

スキーマを複数のファイルに分割することには、いくつかの利点があります。複数のプロジェクトで使用できる再利用可能な定義を作成できます。スキーマを管理しやすい小さな単位に分割するため、定義の読み取りとバージョン管理が容易になります。

...

これはすべて名前空間がなくても正常に機能しますが、異なるチームが異なるファイルで作業を開始すると、名前が衝突する可能性があり、定義がどこから来たのかが常に明らかではありません。解決策は、各スキーマファイルの定義を個別のネームスペースに配置することです。

明確化:

  • XMLスキーマの主な目的は、「語彙」を宣言することです。

  • これらの語彙は、targetNamespace属性で指定された名前空間によって識別できます。

  • スキーマ(XMLドキュメント)には「名前空間」を含めることができます。ドキュメントが記述する「語彙」には「targetNamespace」を含めることができます。

  • XMLスキーマがSGML DTD(XMLの元の設計者はDTDで十分だと考えていた)よりも高いレベルの抽象化を提供するように、XMLスキーマ「targetNamespaces」は「単純な名前空間」に対する抽象化レベルを提供します。

'助けてくれる希望

14
paulsm4

TargetNamespaceの機能を理解するには、インスタンスドキュメントとスキーマドキュメントの両方を同時に確認すると役立つと思います。 (インスタンスドキュメントに基づいて)これを考慮してください。

<p:Person
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://localhost:8080/scribble/xml/Person"
        xmlns:v="http://localhost:8080/scribble/xml/Vehicle"
        xsi:schemaLocation="
            http://localhost:8080/scribble/xml/Person
            http://localhost:8080/scribble/xml/person.xsd">
    <name>John</name>
    <age>28</age>
    <height>59</height>
    <v:Vehicle>
        <color>Red</color>
        <wheels>4</wheels>
        <seats>2</seats>
    </v:Vehicle>
</p:Person>

ドキュメントにはデフォルトのネームスペースは指定されていませんが、p:*およびv:*は特定のNS URIにエイリアスされています。スキーマドキュメント自体を見てみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Person"
    elementFormDefault="qualified"
    xmlns:v="http://localhost:8080/scribble/xml/Vehicle">

    <import
        namespace="http://localhost:8080/scribble/xml/Vehicle"
        schemaLocation="http://localhost:8080/scribble/xml/v.xsd"/>

    <element name="Person">
        <complexType>
            <sequence>
                <element name="name" form="unqualified" type="NCName"/>
                <element name="age" form="unqualified" type="integer"/>
                <element name="height" form="unqualified" type="integer"/>
                <element ref="v:Vehicle"/>
            </sequence>
        </complexType>
    </element>

</schema>

そして

<?xml version="1.0" encoding="UTF-8"?>
<schema
    xmlns="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://localhost:8080/scribble/xml/Vehicle"
    elementFormDefault="qualified">

    <element name="Vehicle">
        <complexType>
            <sequence>
                <element name="color" form="unqualified" type="NCName"/>
                <element name="wheels" form="unqualified" type="integer"/>
                <element name="seats" form="unqualified" type="integer"/>
            </sequence>
        </complexType>
    </element>
</schema>

タグの属性を見ると、デフォルトのネームスペースは両方のスキーマドキュメントで「 http://www.w3.org/2001/XMLSchema 」ですが、targetNamespaceは1つですインスタンスドキュメントでエイリアスネームスペースとして使用されます。

targetNamespaceは、スキーマドキュメントの名前空間およびインスタンスドキュメントで指定された他の名前空間に関係なく、インスタンスの予想される名前空間です。

ゲストリストと名札をつけたゲストがいるパーティーを主催するようなものだと考えると、ちょっと助かります。ゲストリストの名前のようなスキーマドキュメントのtargetNamespaceを考えてください。インスタンスドキュメントのエイリアスの有無にかかわらず、xmlnsはゲストの名前タグに似ています。ゲストリスト(州発行のIDのコピーが奇跡的に含まれています)を持っている限り、誰かに出会うたびに、そのIDを検証できます。添付されたパラメーターと一致しない名前タグを付けた人に出くわした場合、おかしくなります(つまり、エラーをスローします)。

スキーマ/インスタンスを使用すると、次のことができます。

スキーマ:

targetNamespace="http://localhost:8080/scribble/xml/Person"
targetNamespace="http://localhost:8080/scribble/xml/Vehicle"

インスタンス:

xmlns:p="http://localhost:8080/scribble/xml/Person"
xmlns:v="http://localhost:8080/scribble/xml/Vehicle"

または...パーティー(別の言い方をしない限り)、家の床、裏庭、またはプールのどこかで遭遇する「v」の愛称を持つゲストは、ゲストのゲストの説明とよく一致します。 http:// localhost:8080/scribble/xml/Vehicle という名前のリスト。または侵入者です。

これらの特別なルールは、VがPのすぐ隣にいる場合にのみハングアウトできる、またはVが存在する場合にのみPがハングアウトできるというようなことを言うかもしれません。この場合、Vが存在する場合、Pはハングする必要がありますが、Aは存在しなくても、Vはほぼどこにでも移動できます。

このように、スキーマは非常に柔軟で、必要なデータ構造をほぼすべて定義し、特定の要素の名前空間(デフォルトまたはプレフィックス)をTNSおよび関連するスキーマに戻すだけで、どこに行くかを追跡できます。

11
jrypkahauer

あなたが何を求めているのか正確にはわかりません。明らかに、スキーマには多くの異なる名前空間のコンポーネントの定義を含めることができ、「これは名前空間Nの要素Eの宣言です」と言う何らかの方法が必要です。 XSDの設計者は、1つのスキーマドキュメント内のすべての宣言が、モジュールのターゲット名前空間と呼ばれる同じ名前空間に属するように言語を設計することを選択しました。別の方法でパッケージ化することもできますが、その違いは非常に表面的なものです。モジュールを名前空間に合わせるという決定の何が間違っていると思いますか?

4
Michael Kay