targetNamespace und xmlns ohne Präfix, was ist der Unterschied?

77

Wenn ich in einem XML-Schemadokument sowohl den targetNamespace als auch die xmlns ohne Präfix habe .

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://example.com/" xmlns="http://example.com/">

Was ist der genaue Unterschied zwischen ihnen? Mein Verständnis ist, dass, wenn Sie eine XML-Datei ohne Präfix haben, alle Elemente ohne Präfix diesen Namespace erhalten und ... verwirrenderweise dasselbe für targetNamespace gilt.

Abe
quelle
1
Möglicherweise fehlen mir einige Kenntnisse zu diesem Thema, aber die Antwort könnte nicht einfach lauten: xmlns ist der Standard-Namespace für DIESES Dokument (das Schemadokument), während der targetNamespace der Namespace ist, den dieses Schemadokument überprüft. Und auf diese Weise sind xmlns und targetNamespace zwei verschiedene Dinge?
Vering
@Die Prüfung meiner Testergebnisse stimmt mit Ihrem ersten Satz überein. Ja, der targetNamespace bezieht sich definitiv auf das Dokument, das das Schema validiert. Das Vorhandensein von targetNamespace scheint auch das Vorhandensein von 'xmlns' oder 'xmlns: xxx' zu erfordern. Tatsächlich können Sie viele 'xmlns: xxx', 'xmlns: yyy' und 'xmlns' miteinander kombinieren und es wird immer noch validiert.
Eigenfeld

Antworten:

80

targetNamespace ist ein "Artefakt" des XML- Schemas . sein Zweck: anzugeben, welchen bestimmten XML-Namespace die Schemadatei beschreibt.

xmlns - Da das XML-Schema ein XML-Dokument ist, kann ein Standard-XML-Namespace für die XML-Datei selbst definiert werden (dies ist das Attribut xmlns). Die Implikationen sind vielfältig: Authoring und Komposition. Beispielsweise muss für die im Schema definierten Elemente, auf die später an anderer Stelle in derselben Datei verwiesen wird, kein Präfix verwendet werden (z. B. ein globaler simpleType, der als Typ für ein Attribut oder Element verwendet wird).

Nach meiner Erfahrung betrachten viele XML-Schema-Autoren dies als "Best Practice". Sie sind also auf dem richtigen Weg.

In Bezug auf XSD schreibt der targetNamespace den Namespace-Teil eines qualifizierten Namens einer Schemakomponente vor, der Elemente, Attribute, Gruppen und Attributgruppen sowie einfache und komplexe Typen enthält. Einige der in einer XSD definierten qualifizierten Namen (Elemente und Attribute) werden "direkt" von einem XML-Instanzdokument verwendet. Andere, z. B. für Typen, können über das Attribut xsi: type in Instanz-XML-Dokumenten referenziert werden . Der Rest (Gruppen, Attributgruppen) dient zur Erleichterung der Schemaerstellung (durch Verweise).

Ich bin auch der Meinung, dass (im Allgemeinen) Leute XSD aus zwei Blickwinkeln entwerfen:

  • um ein vorhandenes XML abzugleichen. In diesem Fall erhalten Sie, wenn Ihr XML Namespaces verwendet, für jeden der verwendeten Namespaces ein XSD-Schemaelement mit einem übereinstimmenden Attribut targetNamespace.

  • reine Modellierung. Sie denken dann an targetNamespace, das einem UML-Paket oder Datenbankschema oder einem Java-Paket oder einem .NET-Namespace ähnelt, und alles, was dies in diesem Fall bedeutet. Grundsätzlich ist es ein Mechanismus, um Namenskollisionen zu vermeiden. Es ist jedoch auch ein Mechanismus zum Partitionieren von Modellen in Themenbereiche usw.

Petru Gardea
quelle
28

Für diejenigen, die immer noch verwirrt sind, betrachten Sie diese drei xsds. Sie alle definieren einen globalen Typ und eine globale Elementdefinition, die darauf verweist.

Zuerst eine xsd wie die oben gepostete. Es verwendet das Präfix 'xsd' für den Schemanamensraum und einen Standardnamensraum für den Zielnamensraum:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns="http://example.com/">

  <xsd:element name="aGlobalElement" type="aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>   
</xsd:schema>  

Jetzt das gleiche xsd, aber Definition und Verwendung eines Namespace-Präfixes für den Ziel-Namespace:

<xsd:schema 
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <xsd:element name="aGlobalElement" type="tns:aGlobalType"/>

  <xsd:simpleType name="aGlobalType">
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType> 
</xsd:schema>  

... und schließlich eine Version, die einen Standard-Namespace anstelle von 'xsd' für den XML-Schema-Namespace verwendet:

<schema 
  xmlns="http://www.w3.org/2001/XMLSchema" 
  targetNamespace="http://example.com/" 
  xmlns:tns="http://example.com/">

  <element name="aGlobalElement" type="tns:aGlobalType"/>

  <simpleType name="aGlobalType">
    <restriction base="string"/>
  </simpleType>
</schema>

Die meisten Schemaautoren wählen die erste oder die letzte, denn wenn die Standard-Namespace-Funktion verfügbar ist, können wir sie auch für etwas verwenden .

Kimbert
quelle
15

xmlns

Das xmlns-Attribut legt den Standardnamenraum des beschriebenen Elements fest. Der Standard-Namensraum wird somit auf alle Elemente innerhalb des beschriebenen Elements angewendet, die keinen expliziten anderen Namensraum für sich deklarieren.

Der Standard-Namensraum ist für WSDL-Dateien auf einen Standardwert festgelegt: http://www.w3.org/ns/wsdl

targetNameSpace

Dieses Attribut enthält den Namensraum Ihres Webdienstes. Sie können diesen Namensraum frei wählen, aber es gibt eine Konvention, die besagt, dass der URI auf die WSDL des Dienstes verweisen soll.

xmlns: tns

Dieser Namensraum sollte auf denselben URI wie das Attribut targetNameSpace festgelegt werden. Auf diese Weise können Sie über dieses Namensraumpräfix (tns) auf den Zielnamenraum verweisen.

Quelle: http://tutorials.jenkov.com/wsdl/description.html

HakunaMatata
quelle
Der URI für den targetNamespace "zeigt" auf nichts - er ist nur eine Kennung für den Namespace. Es kann die URI eines Webdienstes sein, aber es dient immer noch nur zum Beschriften des Namespace.
Suncat2000
4

Namespace bedeutet wie Scope

targetNamespaceist ein Attribut des schemaElements, das den Namespace definiert, dh das Paket in der XSD-Datei. Konventionell verwenden wir URI / URLs, aber wir können jede Zeichenfolge verwenden.

xmlns Dieses Attribut wird verwendet, um Elemente und Datentypen zu referenzieren, die aus dem xmlns-Attributwert für den aktuellen Elementbereich stammen.

Zum Beispiel:

  • xmlns:xsd="http://www.w3.org/2001/XMLSchema"steht mit dem Präfix, da dem xsdNamespace ein Präfix vorangestellt werden sollxsd:
  • xmlns="http://www.w3.org/2001/XMLSchema" ohne Präfix ist Standard
  • xmlns: p = "http://www.example.com/People" hat das Präfix, da dem pNamespace das Präfix vorangestellt werden sollp:

Wo xmlns:xsdund xmlns:psind QNames und xmlnsist lokaler Name.

Das folgende Bild hilft, XSD nach meinem Wissen mit Java-Analogie zu verstehen:

Geben Sie hier die Bildbeschreibung ein

Premraj
quelle
1

Andere Antworten sind hier gut, daher werde ich ihre Erklärungen hier nicht wiederholen. Wenn jedoch jemand mit Java-Hintergrund es einfacher findet, ist hier die Analogie, die ich mir ausgedacht habe:

  1. .xsdDokument ist das Artefakt / die .jarDatei
  2. xmlns ist der

    package com.example
    

    Anweisung deklarieren Sie oben in Ihren Java- Klassen.

Überlegen Sie (analog), ob Sie ein einziges Paket in Ihrem Java-Projekt hatten und alle Klassen innerhalb einer einzigen äußeren Klasse deklariert und definiert sind . Zum Beispiel

    package com.furniture.models

    public class FurnitureShop {

         int noOfTables;
         int noOfChairs;
         int noOfBeds;
         List<Table> tables;
         List<Chair> chairs;
         List<Bed> beds;

         // and now instead of declaring and defining a class for table/chair/bed in a 
         // separate file, you just add it here 
         public static class Table {
             int height;
             int width;
             int length;
             ...
         }

         public static class Chair {
             String color;
             ChairType chairType;
             ...
         }

         public static class Sofa {
             int price;
             String color;
             ...
         }
    }

Auf diese Weise werden verschiedene Elemente .xsdfür ein neues Schema in einer einzigen Datei gruppiert .

  1. targetNamespaceist der Name des von Ihnen erstellten Artefakts . Wie Sie selbst herausfinden können, targetNamespacewird es beim Erstellen eines Schemas in einer .xsdDatei verwendet.

Sobald das Artefakt (oder die .xsdDatei) erstellt wurde, können Sie es wie folgt in anderen Projekten verwenden:

In einem Java-Projekt importieren Sie die Bibliothek mit der Datei pom.xml(oder build.gradle) wie folgt:

    <dependency>
       <groupId>com.furniture</groupId>
       <artifactId>furniture-apis</artifactId>
       <version>1.1.1</version>
    </dependency>

In XML würden Sie das Schema mit "importieren"

    <furniture xmlns="http://furniture.com"/>

=== ANHANG ===

Klarstellung -

  1. xmlnswird sowohl als packageAnweisung als auch als importAnweisung in Java verwendet. In der .xsdDatei xmlnsfungiert sie als " package" -Anweisung, während sie in .xmlDateien als " import" -Anweisung fungiert.
ARCHE
quelle
-1

Nach einigen gründlichen Tests mit xmllint habe ich hier die eindeutige Erklärung gefunden. Betrachten Sie das folgende Schema:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns:p="http://abced.com"
xmlns:q="http://pqr.com"
xmlns="http://yyyzzz.com">

<xsd:element name="recipe" type="recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>
</xsd:schema>

Das obige Schema gilt für das folgende Dokument:

<?xml version="1.0"?>

<recipe xmlns="http://yyyzzz.com">
    Deciphering the purpose of targetNamespace
</recipe>

Der Grund dafür ist, dass xmlns = "http://yyyzzz.com" automatisch an das Element gebunden wird, das auch vom Schema definiert wird! Das heißt, es wird auch an das Rezeptrezept- Element gebunden .

Mit demselben XML-Dokument, jedoch mit leicht geändertem Schema wie unten, wird nun auch der Unterschied überprüft und genauer betrachtet:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema
version="1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://yyyzzz.com"
xmlns="http://eigenfield.aparicio.com"
xmlns:EGboy="http://yyyzzz.com">

<xsd:element name="recipe" type="EGboy:recipeType" />

<xsd:complexType name="recipeType">
    <xsd:simpleContent>
        <xsd:extension base="xsd:string">
        <xsd:attribute name="desc" type="xsd:string"  />
        <xsd:attribute name="archetype" type="xsd:string" />
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

</xsd:schema> 

Ignorieren , wenn die anderen Xmlns verschwunden, sondern genau hinsehen , um type = „EGboy: recipeType“ . Wir können nicht vertrauen mehr auf dem xmlns weil es daher anderen Wert hat, wir das Präfix setzen müssen EGboy vor recipeType .

Das XML - Dokument nicht einmal von der Pflege EGboy Präfix dieses Präfix nur für das Schema auf die richtigen Bezug zu nehmen Xmlns im Fall gibt es viele.

Eigenfeld
quelle