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?
<?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?
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!
If there's a reference to a component such as vr:someType
, then :
you need the namespace declaration so that the processor knows what namespace vr
refers to
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.
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