Understanding XML Namespaces
John Farrow, Visual Programming Limited
This technical note describes what XML namespaces are and how they work
with Ibex PDF Creator.
What are namespaces
A namespace is an identifier used to distinguish between XML element names and attribute names which
might be the same. Use of namespaces prevents problems which might arise when the same element or attribute
name is used by different developers for different reasons.
A namespace is a URI
such as "http://www.w3.org/1999/XSL/Format" which is the namespace for XSL FO, or
"http://www.w3.org/1999/xhtml" which is the namespace for XHTML.
A namespace such as "http://www.w3.org/1999/xhtml" is a string which uniquely identifies the
namespace - the URI used does not necessarily reference a real file.
Prefixed namespace declarations
Namespaces are usually declared at the top of an XSL stylesheet, as attributes of the xsl:stylesheet
element, like this:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
>
</xsl:stylesheet>
The two namespace declarations above declare a namespace prefix (such as "xsl") and
associate this prefix with a namespace URI (i.e. "http://www.w3.org/1999/XSL/Transform").
Once declared the prefix can be used in front of the name of any XML element
or attribute to show that this element is in the namespace associated with the prefix. The prefix
and the element name are separated by a ':' like the xsl:template element shown here:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
>
<xsl:template match="/">
</xsl:template>
</xsl:stylesheet>
When an XSLT processor reads this stylesheet it creates a unique name
for this xsl:template element by associating the namespace URI and the
element name, so xsl:template internally becomes http://www.w3.org/1999/XSL/Transform:template.
The prefix
is just the mechanism for associating the element with the namespace, it does not form part of the element's
unique name
.
When Ibex reads the results of an XSLT transformation, it looks for elements
in the namespace identified by the XSL FO URI ("http://www.w3.org/1999/XSL/Format"), not elements with a prefix of "fo".
Any value can be used for a prefix. For example "xsl" is the commonly used prefix for the
"http://www.w3.org/1999/XSL/Transform" URI. But an example like the one below, which uses
"ss" as the prefix instead of "xsl" is still valid and will function just the same as
if "xsl" has been used as the prefix.
<?xml version="1.0" encoding="utf-8"?>
<ss:stylesheet version="1.0"
xmlns:ss="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
>
<ss:template match="/">
</ss:template>
</ss:stylesheet>
Default namespace declarations
A namespace declared by using the xmlns attribute on an element becomes the default
namespace for that element and all child elements contained within that element. This means any
such child element which does not have a namespace prefix or its own xmlns attribute will
be in the namespace of the containing element which had the xmlns declaration. Looking at this example:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/XSL/Format" >
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="bookdata">
<root>
<layout-master-set>
<simple-page-master master-name="page-layout" page-height="11in" page-width="8in">
<region-body margin="1in" region-name="body" background-color="#dddddd" />
</simple-page-master>
</layout-master-set>
<page-sequence master-reference="page-layout">
<flow flow-name="body">
</flow>
</page-sequence>
</root>
</xsl:template>
</xsl:stylesheet>
The xsl:stylesheet element has xmlns="http://www.w3.org/1999/XSL/Format", which establishes
"http://www.w3.org/1999/XSL/Format" as the default namespace for all child elements
of the xsl:stylesheet element. This means the <root> element on line 8 is in the
"http://www.w3.org/1999/XSL/Format" namespace, which Ibex recognises as the XSL FO namespace.
Whether to use the fo: prefix or not
If a default namespace is not used, then a prefix must be defined and used on each element. The XSL below
is functionally identical to the XSL above. In the XSL above the XSL FO namespace is declared as the
default namespace (by using xmlns="http://www.w3.org/1999/XSL/Format"
on the xsl:template element), whereas in the XSL below there is no default namespace and the "fo" prefix
is used on all elements in the XSL FO namespace.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="bookdata">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master master-name="page-layout" page-height="11in" page-width="8in">
<fo:region-body margin="1in" region-name="body" background-color="#dddddd" />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="page-layout">
<fo:flow flow-name="body">
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
Whether you use the fo: prefix or not is a matter of personal preference. There is no significant
performance difference either way. In the Ibex examples and the manual we use a default namespace
as this makes the examples clearer and easier to understand.
Useful links
The XML Namespaces standard