
This work is licensed under a Creative Commons Attribution-Share Alike 2.0 France License.
Every now and then I have to re-learn xslt to transform xml documents. My mantra is to use the right tool for the right job... so I'm here again struggling with xslt. There is a bit of a love/hate relation between me and this language. I've used a lot during my master thesis transforming an enormous - industry size - software specification (in SDL) to a formal language. This was a very painful way of learning a new language, After that I just used it to perform small tasks, but I always manage to forget part of the specification...
Anyway, just to avoid repeating this error again, the lesson today is about xml namespaces. | Here you can find a lengthy explanation about namespace and all possible related problems to xslt. I stumbled on a very simple case. Why my xslt stylesheet does not work in the presence of namespace ?
A small motivating example. Suppose you have a very simple xml document
and you want to transform it in a different xml document as :
Therefore you want to - change the document root (and namespace) - copy all the content of the element <a> but the element <b> - move the element <b> below <a> - embed the text content of <b> in a CDATA section.
We go one step at the time. First we transform the root element and we change the default namespace. The header of the xsl file is standard except for the declaration of the attribute xmlns:ns="http://mynamespace.org". Since our source xml document as a namespace, we have to match elements in this namespace. In other to do so, we associate a label ns to the namespace http://mynamespace.org and the we use it to match the element <doc>.
The second part is the standard way of copying nodes and contents...
In the third part we match the root element, we create a new element and we copy everything. Since <xsl:apply-templates/> does not have a select it applies by default to all nodes inside the root element.
The result :
Now we want to move the element <b>. We add a new template to match <a> and copy all its content except the node <b>
This template being more specific then the default template we specified at the beginning of the document will be applied to <a> . Then we have to modify the template for the root element in order to copy the content of <a> and the the content of <b> below.
This will give something like this :
Last we want to embed the content of <b> in a cdata section. This is easy as we just need to add an output directive at the beginning of the file. The complete example :
Recent comments
1 day 3 hours ago
2 weeks 2 days ago
2 weeks 6 days ago
4 weeks 3 days ago
7 weeks 6 days ago
15 weeks 4 days ago
15 weeks 6 days ago
16 weeks 2 days ago
16 weeks 3 days ago
16 weeks 3 days ago