Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML Schema import -vs- namespaces bound to prefixes

Tags:

xml

xsd

I am new to XML Schema and am coming across schema documents that bind a number of prefixes to various namespaces in the xsd:schema root element and also import a subset of such schemas. In the rest of the XML Schema document they happily make use of all prefixes bound in the xsd:schema element (whether imported or not).

So what does an import of a namespace signify over 'just' binding that namespace to a prefix?

From the Definitive XML Schema book I read (pg. 66):

an import is used to tell the processor that you will be referring to components from other namespaces

In my understanding, that's also what a binding does, so what's the difference?

concrete example

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           xmlns:vr="http://www.ivoa.net/xml/VOResource/v1.0"
           xmlns:ssap="http://www.ivoa.net/xml/SSA/v1.0"
           xmlns:vm="http://www.ivoa.net/xml/VOMetadata/v0.1"
           targetNamespace="http://www.ivoa.net/xml/SSA/v1.0"
           elementFormDefault="unqualified" 
           attributeFormDefault="unqualified"
           version="1.0pr2">


   <xs:import namespace="http://www.ivoa.net/xml/VOResource/v1.0"
         schemaLocation="http://www.ivoa.net/xml/VOResource/v1.0"/>

   <!--  ... rest of the schema document follows -->

Namespace http://www.ivoa.net/xml/VOResource/v1.0 in the above schema document is both bound to the vr prefix and imported. Other namespaces are only bound to certain prefixes and not imported. The rest of the document uses components from both vr (bound and imported) and ssa (bound but not imported) prefixes. What's the difference?

like image 818
Marcus Junius Brutus Avatar asked Jun 16 '13 17:06

Marcus Junius Brutus


2 Answers

Well, you need to go to the XML basics to understand all those things...

The real XML name (i.e. that of element or attribute... or some XSD component, like complexType or group) is actually not what you see in a particular XML file (or XML schema). You see something like this:

xs:schema

and you think that's the name of <schema> element. But actually, the real name of that element (with which the XML parser/processor operates) is this:

{http://www.w3.org/2001/XMLSchema}schema

The thing in curly brackets denotes the namespace, which is effective the part of the full name.

Namespaces are needed because, for instance, the <schema> element mentioned here is a part of XSD language provided and maintained by W3C. But suppose, someone else also has some kind of schemas (e.g. the schema of working of some big organization) and wants to describe those schemas with their own <schema> elements. What's more, they may end up having both <schema> elements (i.e. their own and W3C) in the same XML file. How, would an XML parser distinguish them?

Here, the namespaces help. They allow extending local XML names (used in XML) with something else, some extra strings long enough to ensure they are always the same in any XML file on Earth. Those long strings are called namespace URIs and that's what you see in the curly brackets above.

But would you be happy to have your XML file filled with the names like this:

{http://www.w3.org/2001/XMLSchema}schema

You won't be able to read anything there, right?

XML provides a way to work around that problem. Instead of writing the whole namespace URI along with each XML name, you just need do declare some shortcut for it. That shortcut is called namespace prefix and you declare it with a special binding attribute xmlns:... e.g.:

xmlns:xs="http://www.w3.org/2001/XMLSchema"

Here xs is that prefix (which represents the namespace). Now, you can write everywhere simply:

xs:schema

The namespace prefix itself is a local thing (local to your XML file). You can equally use any other string for this, e.g. 'xsd':

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

and write then

xsd:schema

The root XML element typically contains declarations of all namespace bindings used in the given XML (though, that is not necessary; a binding is valid for a content of the XML element, in which it is declared).

Of course, some XML files (and XSD) may contain namespace bindings never used later. This is not an error. But this is a sort of untidy work (the same as unused variables in a program).


Now, what is the import element for? It just imports some external XML schema into your schema. Importing means that now you can use in your own declarations any global components defined in that imported schema.

But remember that you always work with the full XML names (i.e. local name + namespace URI), because schema processor does so. The imported external schema describes elements (components) in some different namespace. If you want to reference those components, you need to tell the XML processor about their namespace, which you do through some namespace prefix you bind to the imported namespace URI in your XML.

The import element has two attributes:

<xs:import namespace="http://www.ivoa.net/xml/VOResource/v1.0"
           schemaLocation="http://www.ivoa.net/xml/VOResource/v1.0"/>

The namespace attribute specifies the namespace URI of what you import. The import element is actually supposed to import only different namespaces (not a part of the one you describe with your schema; for that there is another XSD element: include). So, what you do with the import is called importing of a namespace.

The schemaLocation attribute tells the schema parser the physical location of the imported schema (XSD) file. This is optional attribute. Some XML schema software may hold local copies of the XML schemas describing some important namespaces (particularly those maintained by W3C). So, only namespace URI may be enough to hint where they should take the corresponding XSD file itself.


In short:

  • What does namespace binding means? It allows you to introduce a short (namespace prefix) for a namespace URI (which is a long string). By adding the namespace prefix to a local name, you tell the XML processor to which namespace that XML name belongs. Here the 'namespace' is an abstract notion. It just extends any XML names to make them absolutely unique. However, the namespace binding does not assume that there are any schemas with any components defined for that namespace!

  • What does XSD import element do? It imports all global components defined in a certain namespace (in a cetain XML schema) and makes them available in your schema. This has nothing to do with bindings of particular prefixes to URIs!

like image 177
ColdFusion Avatar answered Sep 27 '22 23:09

ColdFusion


If there's a reference to a component such as vr:someType, then :

  1. you need the namespace declaration so that the processor knows what namespace vr refers to

  2. you need the import declaration so the processor knows where to find the component vr:someType

That's a bit of a simplification. In theory the import doesn't tell the processor where to look; the schemaLocation is only a "hint". In practice for most processors the schemaLocation is either the actual location of a schema document, or a URI that can be redirected (e.g. using a catalog) to the actual location.

The specification could have permitted references such as vr:someType to exist without the import, relying on implementation-defined mechanisms to locate schema components for a particular namespace. But it doesn't permit this.

like image 44
Michael Kay Avatar answered Sep 27 '22 21:09

Michael Kay