3

I am trying to understand a XSD schema. I can't post the original schema but it is somewhat as follows. The problem I have is that I don't understand why the same namespace(http://www.test.com/test) is being referred twice, once with prefix and once without prefix. Is this valid? If yes, what purpose it serves?

Also, while generating XML for this XSD, will I use prefix or not?

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com/test" 
xmlns:pre="http://www.test.com/test" targetNamespace="http://www.test.com/test" 
elementFormDefault="qualified" attributeFormDefault="unqualified"> 
  <xs:complexType name="StudentType">
    <xs:sequence>
      <xs:element name="studentId" type="xs:token" />
      <xs:element name="firstName" type="xs:token"/>
      <xs:element name="middleName" type="xs:token" minOccurs="0"/>
      <xs:element name="lastName" type="xs:token"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="students">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="student" type="StudentType" minOccurs="0" maxOccurs="unbounded">
          <xs:unique name="uniqueStudentId">
            <xs:selector xpath="pre:studentId"/>
            <xs:field xpath="."/>
          </xs:unique>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>
kapd
  • 639
  • 1
  • 7
  • 20
  • 1
    It's important to realize that prefixes only have meaning within a single piece of XML, and you're not forced to use the same prefixes that the XSD uses. All of `Hello`, `Hello` and `Hello` are exactly the same thing, from an informational perspective. – Damien_The_Unbeliever Jan 07 '15 at 07:43

2 Answers2

3

The namespace provided without a prefix becomes the default namespace, so all elements below it automatically belongs to that namespace unless they are qualified differently explicitly.

Now the prefixed namespace - I can't see any reason why it should NOT be permitted. As for it's purpose, I'm not sure, but I would guess that it might have something to do with the possibilities of other overriding namespaces further down the hierarchy?

I want to stress again that this is speculation, but imagine you have something like this:

<root xmlns="http://my.default.ns" xmlns:def="http://my.default.ns">
    <class id="1">
        <student>
            This will automatically belong to https://my.default.ns
        </student>
    </class>
    <class id="2" xmlns="http://especially.bright.pupils">
        <student>
            This will belong to http://especially.bright.pupils
        </student>
        <def:student>
          NOTE: THIS student should still belong to https://my.default.ns, 
          since the element prefix relates to the namespace in the root element,
          which has not been overridden. The DEFAULT namespace (without prefix),
          has been overridden at this point, by the namespace defined in the 
          second <class>-element. 
        </def:student>
     </class>
</root>

Here, the explicit naming of a "default" student using <def:student> stops it from being overridden by a new default namespace below.

Note that it could still be overridden if xmlns:def is redefined below - it just won't be overridden by the default namespace.


Update in response to comment below (hope I understood your question correctly):

The namespace itself is defined by the URI, so it is the same namespace; what these two references to this namespace do, is specify explicitly that:

  • All elements below this point will by default belong to the namespace http://www.test.com/test (i.e. unless they are overridden, or have some prefix that is linked to a different namespace)
  • Elements below this point that have the prefix pre: will belong to the namespace http://www.test.com/test

In other words, these are two (completely valid) namespace declarations, that just happen to refer to the same namespace.

Remember that a namespace is in essence just a name, which is used for sorting/organizing things that might otherwise look identical.

As for the purpose of TargetNamespaces, see this question.

Community
  • 1
  • 1
Kjartan
  • 18,591
  • 15
  • 71
  • 96
  • Thanks for the reply. So, ideally in the context of this XSD are these two separate namespaces? Or is it the same namespace? As per my understanding, these are different namespaces only when something is qualified by "pre", it will lie in that namespace else it will lie in default. Also, you said namespace without prefix is default namespace. I guess that is decided based upon "targetNamespace" attribute, correct? Sorry for my limited knowledge. – kapd Jan 07 '15 at 08:52
  • Thanks again for your answer. One more doubt though unrelated but what targetNamespace attribute means in this case. – kapd Jan 07 '15 at 09:17
  • See the link I added to a different question relating to targetNamespaces. – Kjartan Jan 07 '15 at 09:30
3

This sort of thing is quite common in XSD.

The targetNamespace defines the namespace of top-level elements, types, etc defined within the schema document. The "name" attribute of these declarations is a local name (it can't be prefixed), and the only way to define the associated namespace is using a targetNamespace declaration.

The xmlns="http://www.test.com/test" declaration affects name references that aren't prefixed, for example type="StudentType": this is implicitly a reference to the type with local name "StudentType" in namespace "http://www.test.com/test".

The xmlns:pre="http://www.test.com/test" declaration affects name references with the explicit prefix "pre". This is needed because the schema includes XPath expressions within xs:selector and xs:field. The XPath specification says that if there's no prefix, the name refers to a name in no namespace, so the only way to refer to a name in a namespace is to allocate a prefix.

So you've got three declarations affecting different kinds of names appearing within the schema document.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164