6

The page w3schools gives the following as one form of schema declaration.

<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns="http://www.w3schools.com"
           elementFormDefault="qualified">
...
...
</xs:schema>

Here,

targetNamespace defines the namespace for the XML document being defined-- which tags (elements) and which attributes can be used in the XML document being defined in "this" XSD.

xmlns=http://www.w3schools.com/schema/schema_schema.asp

, on the other hand, is defining the default namespace for the names in the XML document -- those names that aren't being defined on "this" XSD(?) so, the parser is first looking up the namespace declared in targetNamespace. if it can't find the name in there, going ahead and trying next the one in xmlns (?)

What exactly would i miss if i skip the targetNamespace attribute in the schema declaration above? while I have xmlns, targetNamespace redundant to me since they are referring to the same namespace.

What am i missing?

Note: i've seen What does "xmlns" in XML mean? among some other discussions.

Community
  • 1
  • 1
Roam
  • 4,831
  • 9
  • 43
  • 72

3 Answers3

19

To understand the difference between targetNamespace and xmlns, just think the following.

XSD is a language to describe XML schemas. Any computer language must be expressed somehow, that is, have some operators, keywords ets. All those things are called grammar.

The authors of XSD (that is W3C) have decided not to invent yet another grammar, but to use XML itself for that. So, XSD is expressed in XML. XML is the carrier for it.

Essentially, it is a sort of coincidence. It was chosen by the XSD authors for convenience (and that convenience does exist indeed!). But, that is not a necessary requirement. For instance, there is another XML schema language called RELAX NG, which is not based on XML.

But once XML is the carrier of all XSD texts, you have to deal with the XML-specific things and xmlns is the one. Basically, it assigns the default namespace for the elements of the given XML file. It has nothing to do with the XML schema that happen to be described in that very file. It is just convention for that XML file (no matter what it contains).

The targetNamespace, on the contrary, is the thing of XSD language itself. It specifies, which namespace the XML elements described by the schema will belong to.

There is some redundancy between targetNamespace and xmlns indeed. But there is no way to use (harness) it, so as to eliminate one of them. Just think this:

XML will be parsed and converted into something else (e.g. XML infoset) by an XML parser. Such a parser is not required to know anything about XSD and its output won't be XML. So, all XML specific things will be lost (that is xmlns, namespace prefixes etc).

Then, that infoset (or something else) is passed to the XSD processor, which starts from anew, and it must have all the necessary information at hand. So, the targetNamespace will be the only thing to tell it about the target namespace of that XML schema!

ColdFusion
  • 2,381
  • 13
  • 14
  • thx for the answer. sounds like what i'm looking to find out but cant pin it down just yet. new to XSD. will write again in a day or so. – Roam Aug 27 '13 at 22:50
9

A schema defines a set of types, element, attributes, etc. These components are defined in a specific namespace if the targetNamespace attribute is specified, or in the empty namespace (or no namespace) if there are no targetNamespace attribute. Hence, the targetNamespace is essential to the semantics of your target XML documents: Do the elements live in a certain namespace or not?

The xmlns attribute in the schema is more or less a convenience thing and means nothing in terms of the semantics of your target documents. There are consequences in how you refer to data types and components within the schema.

Consider these two alternatives. In the first alternative the default namespace is the same as the target namespace.

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

    <xsd:simpleType name="Animal">
        <xsd:restriction base="string">
            <xsd:enumeration value="Dog" />
            <xsd:enumeration value="Cat" />
        </xsd:restriction>
    </xsd:simpleType>

    <xsd:element name="animal" type="Animal" />
    <xsd:element name="date" type="xsd:dateTime" />

</xsd:schema>

In the second alternative, the default namespace is the same as the XML Schema namespace. Note how the type references are "inverted".

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

    <simpleType name="Animal">
        <restriction base="string">
            <enumeration value="Dog"/>
            <enumeration value="Cat"/>
        </restriction>
    </simpleType>

    <element name="animal" type="tns:Animal" />
    <element name="date" type="dateTime" />

</schema>

However, regardless of the alternative, both <animal> and <date> lives in the http://www.example.com/animal namespace. The document

<animal xmlns="http://www.example.com/animal" />

would be valid for both alternatives.

zx485
  • 28,498
  • 28
  • 50
  • 59
forty-two
  • 12,204
  • 2
  • 26
  • 36
  • thx for the answer. sounds like what i'm looking to find out but cant pin it down just yet. new to XSD. will write again in a day or so. – Roam Aug 27 '13 at 22:49
6

The difference between targetNamespace and a default namespace declaration (xmlns=...) may become clearer if you consider two simple examples. First:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://example.com/ns"
           xmlns:tns="http://example.com/ns"
           xmlns:ns2="http://example.com/ns2"
           elementFormDefault="qualified">

   <xs:import namespace="http://example.com/ns2"/>

   <xs:complexType name="T1"/>
   <xs:element name="doc" type="tns:T1"/>
   <xs:element name="note" type="ns2:T1"/>
</xs:schema>

Nothing complicated here: the schema document declares one complex type and two elements, all in the target namespace http://example.com/ns. Since they are in a namespace, any document that refers either to the element declarations or the type definition will need to use a namespace-qualified name.

The two element declarations each refer to a type; both types have the local name T1, but they are in different namespaces, so the qualified names tns:T1 and ns2:T1 are different.

The second example declares exactly the same elements and type, but uses slightly different XML syntax in the declarations:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://example.com/ns"
           xmlns="http://example.com/ns"
           xmlns:ns2="http://example.com/ns2"
           elementFormDefault="qualified">

   <xs:import namespace="http://example.com/ns2"/>

   <xs:complexType name="T1"/>
   <xs:element name="doc" type="T1"/>
   <xs:element name="note" type="ns2:T1"/>
</xs:schema>

The only difference is that the namespace http://example.com/ns is declared as the default namespace (using xmlns="http://example.com/ns"), so the element declaration for doc can use an unqualified name to refer to type T1 in that namespace.

The default namespace could just as easily be made to be http://example.com/ns2 -- or (as shown in one of the examples offered by @forty-two) http://www.w3.org/2001/XMLSchema.

When you understand how these two examples work, you will understand how the targetNamespace attribute and the default namespace declaration relate to each other (and why not).

C. M. Sperberg-McQueen
  • 24,596
  • 5
  • 38
  • 65
  • I got it, targetNamespace is XSD specific, it will determines in which namespace will be the types declared in the schema, xmlns is XML specific to specify the default namespace for the xml elements. – Olivier Boissé Jan 20 '17 at 14:20
  • 2
    No. The targetNamespace attribute specifies the namespace part of the name of all top-level elements, attributes, and types declared in the schema document; the xmlns attribute specifies how unprefixed names will be interpreted. – C. M. Sperberg-McQueen Jan 24 '17 at 00:18
  • So bascially `xmlns` is like an "import", to use an existing namespace and `targetNamespace` defines a (new) namespace? – das Keks Aug 19 '21 at 14:14
  • 1
    @dasKeks - well, no, those are not the words I would use, nor the words most people use. A namespace declaration of the form `xmlns="..."` determines how an XML parser will interpret unprefixed names appearing within its scope, just as `xmlns:foo="..."` determines how they will interpret names with a prefix of `foo`. Namespace declarations may be used in any XML document. The XSD `xsd:schema/@targetNamespace` attribute specifies the namespace name for all top-level elements and types declared or defined in the schema document. – C. M. Sperberg-McQueen Aug 19 '21 at 16:05