Maybe the question's title is misleading, and that is because I couldn't explain my problem in a single line sentence.
In the w3school tutorial, there is this example:
<?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>
The author has stated that: xmlns:xs="http://www.w3.org/2001/XMLSchema"
means:
the elements and data types used in the schema come from the "http://www.w3.org/2001/XMLSchema" namespace. It also specifies that the elements and data types that come from the "http://www.w3.org/2001/XMLSchema" namespace should be prefixed with xs.
However, the author has also stated that targetNamespace="http://www.w3schools.com"
means:
the elements defined by this schema (note, to, from, heading, body.) come from the "http://www.w3schools.com" namespace.
I have a problem understanding the previous paragraphs. The first one states that the elements come from http://www.w3.org/2001/XMLSchema
namespace, though the second paragraph states that the elements come from http://www.w3schools.com
namespace.
In my opinion, these two sentences conflict with each other.
Could you tell me please which one is correct? and what does each one really mean?
I appreciate your time.
Regards,
The default namespace is the one that is not mapped to any prefix. You declare it using:
xmlns="a-string-that-is-usually-an-uri"
If you have such a declaration in an XML file, any unprefixed element will belong to that namespace. Unprefixed attributes always belong to no namespace.
You can have several namespace declarations in an XML document, but only one default namespace in each scope. You also don't need to have any default namespace. A scope consists of the element itself and its descendants. In the document below, there are two default namespaces. The ns2
namespace replaces ns1
in the element it is declared in and its descendants:
<root xmlns="ns1">
<text>This is ns1</text>
<child xmlns="ns2">
<text>This is ns2</text>
</child>
</root>
There are two <text>
elements in the document above. Actually they are completely different elements since each one belongs to a different namespace. They have the same local name but their qualified names differ.
If you have a declaration for the same namespace such as:
xmlns:p="a-string-that-is-usually-an-uri"
You are mapping the namespace with a prefix p
which can be used by any element in the context (considering a well-formed document, not necessarily valid). For a valid document, elements that are part of a namespace should be qualified by it, either as an unprefixed descendant (or self) of an element which declares a default namespace, or as a prefixed descendant (or self) of an element which declares a namespace mapping to that prefix. Prefixes can also be used to qualify attributes.
By using prefixes you can have all declarations at the root element, and qualified elements can mix:
<root xmlns:p="ns1" xmlns:q="ns2" xmlns="ns0">
<p:text>This is ns1</p:text>
<q:child xmlns="ns2">
<q:text>This is ns2</q:text>
<p:text>This is ns1 again!</p:text>
<text>This is ns0</text>
</q:child>
</root>
Each one of the <text>
elements above are part of a different namespace.
Take some time to read this guide: Understanding XML Namespaces. It's short and if you read it carefully, you'll certainly understand how namespaces in XML work very well. If you wish, you can also read the XML Namespaces specification which is the official documentation.
About the tutorial you are reading. This file:
<?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>
has two namespace declarations, and one target namespace declaration. Since it's also a schema, it contains type definitions which will belong to the target namespace. This may be confusing because the schema is a XML document which declares rules for other XML documents using XML. Treating the XSD document as a plain XML document, you have one namespace mapped to the xs
prefix and another which is the default namespace. You could also have legally used different prefixes:
<abc:schema xmlns:abc="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns:xyz="http://www.w3schools.com"
elementFormDefault="qualified">
<abc:complexType name="MyType"> ...</abc:complexType>
<abc:element name="myElementOne" type="xyz:MyType" />
<abc:element name="myElementTwo" type="abc:string" />
</abc:schema>
If you look carefully at the example above you might see the associations:
schema
, complexType
and element
elements, plus the string
type all belong to the http://www.w3.org/2001/XMLSchema
namespace.http://www.w3schools.com
namespace, since this is a schema and it's actually defining those elements.MyType
complex type is part of the http://www.w3schools.com
namespace. This is because it's being declared in the schema and the targetNamespace
of the schema is http://www.w3schools.com
. Since that namespace is mapped to the xyz
prefix, then you need to prefix
it when you refer to it That's what is happening in the type
attribute of the first element, the same way the type
attribute of the second element refers to the string
type of the http://www.w3.org/2001/XMLSchema
namespace.You could also have written the above schema like this. It would make no difference:
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns:xyz="http://www.w3schools.com"
elementFormDefault="qualified">
<complexType name="MyType"> ...</complexType>
<element name="myElementOne" type="xyz:MyType" />
<element name="myElementTwo" type="string" />
</schema>
Note now that there is a default namespace, and it's http://www.w3.org/2001/XMLSchema
, so all types and elements of that namespace are unprefixed.
It's best, however, to follow conventions and map a prefix to the XSD namespace (usually xs
or xsd
).
Actually, they are not conflicting. But they are not well written (they might be, perhaps, in their original context). The first one:
the elements and data types used in the schema come from the "http://www.w3.org/2001/XMLSchema" namespace. It also specifies that the elements and data types that come from the "http://www.w3.org/2001/XMLSchema" namespace should be prefixed with xs.
Consider the XSD document as a regular XML file. In any XML file, a namespace declaration such as xmlns="ns1" in the root element is declaring that the unprefixed elements come from the ns1
default namespace. In the case described by the sentence, the author is referring to all the prefixed elements (such as element
, complexType
, simpleType,
sequence) and types (such as
string,
integer,
decimal) because the
xs` prefix is mapped to the XSD namespace. The author is talking about elements and types used in the XML file, not defined.
The next sentence is about targetNamespace
, which is an attribute specific to the XSD specification. It declares the namespace of all the types:
targetNamespace="http://www.w3schools.com" means that the elements defined by this schema (note, to, from, heading, body.) come from the "http://www.w3schools.com" namespace.
This refers to the names you are assigning to types and elements. When you create an instance that declares that namespace, then you will be using these elements:
<note xmlns="http://www.w3schools.com">...</note>
or
<x:note xmlns:x="http://www.w3schools.com">...</x:note>
But in the XSD you are defining them. You don't even need to declare xmlns="http://www.w3schools.com"
in the schema if you never refer (using attributes such as type
, ref
, etc.) to any other type or element you created inside it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With