None of the above answers made sense to me until I read something on the Microsoft website. Maybe this will help someone understand the difference between "targetNamespace" and "xmlns".
"Xmlns" does one thing: it sets the default namespace for all xml (elements and attributes) INSIDE only your schema file.
"TargetNamespace" performs two functions: it changes the default namespace that you specified using "xmlns" to a new namespace in the schema file AND sets the namespace for all xml documents received from it, and not inside it. The one exception is that its own elements refer to their own types within the schema (see below).
Let's dig into the details to understand what this means:
The "TargetNamespace" in the schema simply tells the parser to move the namespace from the default to the namespace "targetNamespace" , where "xmlns" sets the default namespace before the "targetNamespace" is set. "TargetNamespace" cannot be used until you have set the default namespace using "xmlns".
Example. This works because the default namespace was set first and then changed:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="abc" targetNamespace="def">
This fails because the default namespace is not set at first:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="def">
The above will result in an error because xmlns = 'xxxxx' or the default namespace is not defined. If you add the attribute "targetNamespace" with a value to a schema for which a namespace is not defined - i.e. it has an empty namespace or xmlns = "" - you get an error. What for? You receive an error message because you cannot change the namespace if it has not been installed or is empty. By the way ... xmlns = "" is the same as an empty, empty, or empty namespace in the XML world. But this is the first rule.
It then turns out that each XML document or schema document has an empty default namespace . This is the same as saying xmlns = "". When you add the attribute "xmlns = 'xxxxx'" with a value, you set each tag and attribute in the xml file to a new default namespace. You cannot add "targetNamespace" until it is set, which is a CHANGE in the namespace for each tag in XML.
Let's talk about how the new default namespace is used.
When you set the attribute "xmlns" to a value, you simply say: first set the default namespace using "xmlns". Later, of course, you can change it, even to the same default namespace, using "targetNamespace" as follows:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="abc" xmlns="abc">
The above means that you set the default namespace for the schema and then reset it to the default again. xmlns must be set first, and targetNamespace second. Of course you can make them different.
One note about using a target with an empty namespace. You can add "targetNamespace" as a child link or alias to an empty namespace as follows. This is pretty common:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="abc" xmlns:tns="abc">
But what does that mean? The default namespace remains empty (xmlns = ""), but the alias "tns" is now available as a child of the empty namespace and is used to define specific elements inside your xml using the new targetNamespace. In this scenario, you have an empty namespace, but certain attributes within your schema will have their own namespace using an alias, for example:
<xs:element name="hello" type='tns:MyType' />
This then explains the difference between the two attributes, but does not explain WHY you need both "targetNamespace" and "xmlns".
It turns out that setting your default namespace for your schema, “xmlns = 'xxxxx'”, but NOT setting the target namespace, “targetNamespace = 'xxxxx'”, will install all your xml tags in the new namespace, but will not be allowed outside are xml instances that use a schema or even your schema to access their own types.
Thus, the addition of "targetNamespace" not only changes the default xmlns namespace, but also controls how the scheme accesses its own types. For example, the following code example fails because it lacks targetNamespace. This value is necessary for the schema to assign its simple type to the namespace and gain access to this simple type from its own schema element below. Although a default namespace has been assigned, the custom "simpleType" accessible from the element cannot access it because it was not associated with the target schema namespace. This explains the difference:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="abc"> <xsd:element name="myelementname" type="mytype"/> <xsd:simpleType name="mytype"> <xsd:restriction base="xsd:string"/> </xsd:simpleType> </xsd:schema>
The code below will be fine, since targetSchema has been added and tells the schema that its types are also part of the namespace and are accessible, and the schema can refer to its own types using the new namespace without an alias.
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="abc" xmlns="abc"> <xsd:element name="myelementname" type="mytype"/> <xsd:simpleType name="mytype"> <xsd:restriction base="xsd:string"/> </xsd:simpleType> </xsd:schema>
Anyone who has designed this XSD circuit system should return to the drawing board if you ask me. But at least it helps to understand what we're stuck with.