In the final installment of this series exploring the fundamentals of XML (eXtensible Markup Language) and its partner tool, XSLT (eXtensible Stylesheet Language Transformation), I’ll identify a few common problems you are likely to encounter and provide practical XSLT samples for transforming XML into other formats that may be more convenient for your purposes.
Problem 1 – Why do I get extra text in my output?
Answer: Built-in Templates. XSLT beginners often find unwanted unstructured text outside carefully designed and highly structured output. The extra text is likely the result of the XSLT processor applying a built-in template. When <xsl:apply-templates> is invoked and no matching template is found in the stylesheet, the processor invokes a default built-in template that lives inside the processor.
The primary built-in template matches any element and then calls <xsl:apply-templates> passing the current element’s child elements for further processing. This template gives XSLT its automatic recursive feature for all elements that have no explicit template in the transform.
The built-in template for text nodes (text between Element Open and Close tags) copies the text to the output. This built-in template causes great confusion if you don’t understand the way the processor handles unmatched nodes.
You can easily see the results of this behavior by transforming an XML document with a stylesheet that contains no templates as shown here.
<xsl:stylesheet version=”1.0” xmlns:xsl=”http://www.
There are also built-in templates for comments and processing instructions that do absolutely nothing. Built-in templates have a lower priority than all other templates. Thus, you may override a built-in template by creating your own template.
To override the built-in template for text nodes, simply include the following template in your stylesheet.
If you have other templates for processing text nodes, their match patterns will be more specific than this pattern and will, therefore, be matched by the XSLT processor as having higher priority than this template. Add this one-line template to a blank stylesheet and see that it produces a blank output file—a great starting point when developing new transforms.
Problem 2 – None of my templates work when the XML file includes a default namespace.
Dealing with a default namespace can be a little tricky. Because the designers of XSLT decided that terseness is of minimal importance, XSLT is verbose and explicit in most cases, but default namespaces are uncharacteristically non-explicit and can result in confusion and frustration.
Remember that all elements in an XML document must belong to a namespace. In fact, there is no way to create an XML element that is not part of any namespace. This may seem confusing if you often work with XML documents that include no namespace declarations. Document elements with no declared namespace actually belong to a default null namespace and require no special namespace modifier in match patterns or XPath expressions. A non-null default namespace is one that does not include a namespace alias prefix. The following examples will illustrate this fine point.
In this sample, RecipeElement and OtherElements are included in the default null namespace and may be matched in XSLT expressions as RecipeElement or OtherElements, respectively.
In this sample, RecipeElement and its children (OtherElements) belong to the default namespace, urn:Rockwell/MasterRecipe because the namespace does not include a prefix after xmlns. These will no longer be matched by RecipeElement and OtherElements. To match these, the namespace must be declared with a prefix in the stylesheet; for example, xmlns:rs=”urn:Rockwell/MasterRecipe”.
Remember the value of this attribute must exactly match the namespace as it is declared in the XML file. It is case-sensitive. This declaration includes the prefix rs that may now be used for match expressions, such as rs:RecipeElement and rs:OtherElements, respectively. Remember that because the namespace is declared as a default namespace in the XML document, all child elements inherit from this same namespace, unless explicitly overridden by use of another namespace prefix.