Understanding XML Namespaces
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.