web-dev-qa-db-de.com

Warum brauchen wir targetNamespace?

Ich möchte den Zweck von targetNamespace verstehen, wie er sowohl im XML-Schema als auch in der WSDL verwendet wird. Um die Sache einfach zu halten, beschränken wir diese Frage auf das XML-Schema.

Ich habe das Gefühl, den Begriff (einfacher) XML-Namespaces vollständig zu verstehen. Konventionell verwenden wir URI/URLs, aber wir können jeden String verwenden, den wir dann einem Präfix zur Wiederverwendung durch XML-Knoten und -Attribute zuweisen, oder einfach als Standard-Namespace für den vorliegenden Bereich verwenden. So weit, ist es gut ?

Tritt nun in das XML-Schema ein. Aus irgendeinem Grund waren die Erfinder des XML-Schemas der Ansicht, dass die Vorstellung von einfachen Namespaces nicht ausreichte und sie mussten den targetNamespace einführen. Meine Frage ist: Welchen signifikanten Vorteil bietet ein targetNamespace, den ein normaler XML-Namespace nicht bieten kann? Wenn ein XML-Dokument auf ein xsd-Dokument verweist, entweder über schemaLocation oder mit einer import-Anweisung, gebe ich in beiden Fällen den Pfad zum tatsächlichen xsd-Dokument an, auf das verwiesen wird. Auf diese Weise wird das Schema, auf das ich verweisen möchte, eindeutig definiert. Wenn ich dieses Schema zusätzlich an einen bestimmten Namespace in meinem referenzierenden Dokument binden möchte, warum muss ich dann den genauen targetNamespace replizieren, der bereits in dem XML-Schema definiert ist, auf das ich verweise? Warum konnte ich diesen Namespace nicht einfach neu definieren, obwohl ich dies innerhalb des XML-Dokuments möchte, in dem dieser Namespace verwendet wird, um auf das bestimmte XML-Schemadokument zu verweisen, auf das ich verweisen möchte?

Aktualisieren:

Um ein Beispiel zu geben, wenn ich Folgendes in einem XML-Instanzdokument habe:

<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>

Warum tut z.B. Muss das people.xsd-Schema einen targetNamespace definieren, der "http://contoso.com/schemas/People" lautet? Warum brauchen wir überhaupt die targetNamespace-Definition im xsd-Dokument? Mir scheint, dass alles, was Sie mit dem Namespace-Teil des Schemas erreichen können, bereits im XML-Instanzdokument enthalten ist. Welchen Vorteil hat es, die Existenz eines targetNamespace mit gleichem Wert im xsd-Dokument zu erzwingen?

Folgefrage zu Pauls Antwort:

Können Sie mir ein konkretes Beispiel geben, wo solche "Kollisionen" zwischen xsd-Elementnamen offensichtlich werden und das die Notwendigkeit von targetNamespace erklären würde?


Ok, hier ist ein Versuch, meine eigene Frage zu beantworten. Lassen Sie mich wissen, ob es Ihnen schlüssig erscheint. Ein Blick auf die Beispiele auf der von Paul verlinkten Seite hat mir geholfen.

Wenn wir das XML-Instanzbeispiel in der obigen ursprünglichen Frage heranziehen, haben wir zwei Verweise auf die Definition des Fahrzeugelements. Eines ist explizit und im XML-Instanzdokument selbst sichtbar, aber wir müssen uns auch vorstellen, dass das XML-Schema person.xsd erneut auf dieselbe Fahrzeugdefinition als zulässiges untergeordnetes Element der Person verweist. Wenn wir normale Namespaces verwenden würden, in denen jedes Dokument einen eigenen Namespace für das Fahrzeug definieren darf, wie würden wir dann wissen, dass die XML-Instanz auf dieselbe XML-Schemadefinition für das Fahrzeug verweist wie die Datei person.xsd? Der einzige Weg besteht darin, ein Konzept des Namespace durchzusetzen, das strenger ist als das ursprüngliche, einfache Konzept und das über mehrere Dokumente hinweg genauso geschrieben werden muss.

Wenn ich dies nicht auf einem Tablet schreiben würde, würde ich ein Codebeispiel bereitstellen, aber hier werde ich nur versuchen, das Beispiel zu beschreiben, an das ich denke.

Stellen Sie sich vor, wir haben zwei verschiedene XML-Schemadefinitionen für ein Fahrzeugelement. location1/vehicles.xsd würde die Definition enthalten, die das Beispiel aus der Frage dieses Beitrags validiert (mit untergeordneten Elementen für Farbe, Räder und Sitze), wohingegen location2/vehicles.xsd eine völlig andere Definition für ein Fahrzeugelement enthalten würde (z. B. , mit untergeordneten Elementen (Jahr, Modell und Volumen). Wenn sich das XML-Instanzdokument auf das Schema location1 bezieht, wie im obigen Beispiel, aber person.xsd besagt, dass das Element person ein untergeordnetes Fahrzeugelement des im Schema location2 definierten Typs enthalten kann, dann ohne den Begriff Von einem targetNamespace würde die XML-Instanz validiert, obwohl sie eindeutig nicht die richtige Art von Fahrzeug als untergeordnetes Element ihres person-Elements hat.

Mithilfe von Zielnamespaces können wir dann sicherstellen, dass zwei unterschiedliche Dokumente, die auf dasselbe dritte XML-Schema verweisen, auf dasselbe Schema verweisen und nicht nur auf ein Schema, das Elemente enthält, die ähnlich, aber nicht identisch sind. .

Macht das irgendeinen Sinn ?

50
Student

Sie scheinen auf dem richtigen Weg zu sein. Ich werde hier einige Punkte ansprechen, die helfen könnten.

  • In einem Instanzdokument verwenden Sie XML-Namespaces, um den Namespace zu identifizieren, in dem sich ein Element oder Attribut befindet.
  • Innerhalb eines Schemadokuments deklarieren Sie Elemente und Attribute, die in Instanzen angezeigt werden. In welchem ​​Namespace sollen sie sich befinden? Dafür ist targetNamespace da.
  • Der Speicherort des Schemadokuments und der Namespace sind nicht dasselbe. Es ist durchaus üblich, dass mehrere .xsd-Dokumente denselben targetNamespace haben. (Sie können sich gegenseitig einschließen oder auch nicht, schließen sich jedoch normalerweise gegenseitig ein.)
  • Instanzdokumente verfügen nicht immer über ein xsi: schemaLocation-Element, das Parsern mitteilt, wo sie die Schemas finden sollen. Es können verschiedene Methoden verwendet werden, um einem Parser mitzuteilen, wo relevante Schemadokumente zu finden sind. Eine XSD befindet sich möglicherweise auf einer lokalen Festplatte oder unter einer bestimmten Webadresse. Dies sollte den Namespace der darin enthaltenen Elemente nicht beeinflussen.
    • xsi: schemaLocation ist ein Hinweis. Parser können das Schema für den angegebenen Namespace an einer anderen Stelle finden, was bedeutet, dass sie wissen müssen, für welchen Namespace ein Schema bestimmt ist.
    • Tools wie Datenbindungs-Tools kompilieren Schemas vor und erzeugen Code, der gültige Dokumente erkennt. Diese müssen die Namespaces der deklarierten Elemente kennen.

Ich denke, Sie gingen davon aus, dass das Instanzdokument den Namespace der in einem Schemadokument deklarierten Elemente und Attribute mithilfe von xsi: schemaLocation angeben könnte. Das geht nicht Zum einen kann der Parser andere Schemadokumente als die aufgelisteten finden, und er muss wissen, für welchen Namespace sie bestimmt sind. Zum anderen würde es das Denken über Schemata erschweren oder unmöglich machen: Sie könnten sich kein Schema ansehen und die Namespaces kennen, zu denen alles gehört, da diese Entscheidung verschoben würde, bis eine Instanz geschrieben wurde.

17
Kevin

F: "Konventionell verwenden wir URI/URLs, aber wir können jede beliebige Zeichenfolge verwenden, die wir dann einem Präfix für die Wiederverwendung durch XML-Knoten und -Attribute zuweisen oder einfach als Standard-Namespace für den jeweiligen Bereich verwenden."

A: Ja genau.

F: "Aus irgendeinem Grund waren die Erfinder des XML-Schemas der Ansicht, dass die Vorstellung von einfachen Namespaces nicht ausreicht, und sie mussten den targetNamespace einführen."

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

Das Aufteilen von Schemas in mehrere Dateien kann mehrere Vorteile haben. Sie können wiederverwendbare Definitionen erstellen, die für mehrere Projekte verwendet werden können. Sie vereinfachen das Lesen und die Versionierung von Definitionen, da sie das Schema in kleinere Einheiten aufteilen, die einfacher zu verwalten sind.

...

Ohne Namespaces funktioniert dies problemlos. Wenn jedoch verschiedene Teams mit der Arbeit an verschiedenen Dateien beginnen, kann es zu Namenskonflikten kommen, und es ist nicht immer klar, woher eine Definition stammt. Die Lösung besteht darin, die Definitionen für jede Schemadatei in einem eigenen Namespace zu platzieren.

Klärung:

  • Der Hauptzweck von XML-Schemas ist die Deklaration von "Vokabularen".

  • Diese Vokabulare können durch einen Namespace identifiziert werden, der im Attribut targetNamespace angegeben ist.

  • Das Schema (ein XML-Dokument) kann einen "Namespace" haben. Das im Dokument beschriebene "Vokabular" kann einen "targetNamespace" haben.

  • So wie XML-Schemata eine höhere Abstraktionsebene als SGML-DTDs bieten (die ursprünglichen Architekten von XML hielten DTDs für ausreichend), bieten XML-Schema "targetNamespaces" eine Abstraktionsebene über "einfache Namespaces".

'Ich hoffe, das hilft

14
paulsm4

Ich denke, es hilft, das Instanzdokument und das Schemadokument gleichzeitig zu betrachten, um zu verstehen, was targetNamespace tut. Beachten Sie Folgendes (basierend auf Ihrem Instanzdokument):

<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>

Für das Dokument ist kein Standardnamespace angegeben, aber p: * und v: * sind auf bestimmte NS URIs ausgerichtet. Schauen Sie sich nun das Schemadokument selbst an:

<?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>

und

<?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>

Wenn Sie sich die Attribute in den Tags ansehen, ist der Standardnamespace für beide Schemadokumente " http://www.w3.org/2001/XMLSchema ", aber der targetNamespace ist derjenige Wird als Alias-Namespace im Instanzdokument verwendet.

targetNamespace ist der erwartete Namespace der Instanzen, unabhängig vom Namespace der Schemadokumente und allen anderen im Instanzdokument angegebenen Namespaces.

Ich finde es irgendwie hilfreich, daran zu denken, wie eine Party zu veranstalten, bei der man eine Gästeliste hat und Gäste Namensschilder tragen. Stellen Sie sich den targetNamespace in den Schemadokumenten wie die Namen in der Gästeliste vor. Die xmlns, ob mit oder ohne Alias, in den Instanzdokumenten entsprechen den Namensschildern der Gäste. Solange Sie die Gästeliste haben (die auf wundersame Weise eine Fotokopie ihres vom Staat ausgestellten Personalausweises enthält), können Sie bei jeder Begegnung mit jemandem deren Identität überprüfen. Wenn Sie auf jemanden stoßen, der ein Namensschild trägt, das nicht den angehängten Parametern entspricht, können Sie ausflippen (d. H. Einen Fehler auslösen).

Mit dem Schema/den Instanzen haben Sie:

Schemata:

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

Beispiel:

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

Oder ... jeder Gast mit dem Spitznamen "v", dem Sie überall in der Gruppe begegnen (mit Ausnahme von Sonderregeln, die anders lauten), jeder Etage des Hauses oder im Hinterhof oder im Pool, entspricht besser der Beschreibung für einen Gast im Gast Liste mit dem Namen http: // localhost: 8080/scribble/xml/Vehicle . oder sie sind ein Eindringling.

Diese Sonderregeln können wie folgt lauten: V kann nur hängen bleiben, wenn sie sich unmittelbar neben P befinden, oder P kann nur hängen bleiben, wenn V vorhanden ist. In diesem Fall muss P hängen, wenn V da ist, aber V kann so ziemlich überall hingehen, ohne dass A da ist.

Auf diese Weise kann ein Schema unglaublich flexibel sein, praktisch jede gewünschte Datenstruktur definieren und verfolgen, was wohin geht, indem einfach die Namespaces (Standard oder Präfix) eines bestimmten Elements wieder mit dem TNS und dem zugeordneten Schema abgeglichen werden.

11
jrypkahauer

Mir ist nicht klar, wonach Sie fragen. Es ist klar, dass ein Schema Definitionen von Komponenten in vielen verschiedenen Namespaces enthalten kann, und es muss eine Möglichkeit geben, "Dies ist eine Deklaration von Element E in Namespace N" zu sagen. Die Entwickler von XSD haben die Sprache so entworfen, dass alle Deklarationen in einem Schemadokument zu demselben Namespace gehören, dem Zielnamespace des Moduls. Es hätte anders verpackt werden können, aber der Unterschied wäre sehr oberflächlich. Was genau ist Ihrer Meinung nach falsch an der Entscheidung, Module an Namespaces auszurichten?

4
Michael Kay