How do I make transformation follow xml node order?
The xml file is something like this
<root>
<paragraph>First paragraph</paragraph>
<paragraph>Second paragraph</paragraph>
<unordered_list>
<list_name>Unordered list name</list_name>
<list_element>First element</list_element>
<list_element>Second element</list_element>
</unordered_list>
<paragraph>Third paragraph</paragraph>
</root>
I would like to transform it to HTML
...
<p>First paragraph</p>
<p>Second Paragraph</p>
<h3>Unordered list name</h3>
<ul>
<li>First element</li>
<li>Second element</li>
</ul>
<p>Third paragraph</p>
...
When I use xsl:for-each
It outputs all paragraphs first and then the list, or the other way round.
I want to keep the order of the XML file.
I am aware this might be very basic but I seem to be getting nowhere using xsl:choose and xsl:if. So please help me someone.
Here is a sample xslt stylesheet that does exactly what you are looking for:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- iterate through all the child nodes,
and apply the proper template to them -->
<xsl:template match="/">
<!-- added an extra div tag, to create a correct xml
that contains only one root tag -->
<div>
<xsl:apply-templates />
</div>
</xsl:template>
<!-- create the **p** tags -->
<xsl:template match="paragraph">
<p>
<xsl:value-of select="text()" />
</p>
</xsl:template>
<!-- create the **ul** tags -->
<xsl:template match="unordered_list">
<h3>
<xsl:value-of select="list_name" />
</h3>
<ul>
<xsl:apply-templates select="list_element" />
</ul>
</xsl:template>
<!-- create the **li** tags -->
<xsl:template match="list_element">
<li>
<xsl:value-of select="text()" />
</li>
</xsl:template>
</xsl:stylesheet>
The output of this transformation will be:
<?xml version="1.0" encoding="UTF-8"?>
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
<h3>Unordered list name</h3>
<ul>
<li>First element</li>
<li>Second element</li>
</ul>
<p>Third paragraph</p>
</div>
A shorter and more consize transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="paragraph">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="unordered_list/list_name">
<h3><xsl:apply-templates/></h3>
</xsl:template>
<xsl:template match="unordered_list/list_element"/>
<xsl:template match="unordered_list/list_element[1]">
<ul>
<xsl:apply-templates mode="list"
select=".|following-sibling::*"/>
</ul>
</xsl:template>
<xsl:template mode="list" match="unordered_list/list_element">
<li><xsl:apply-templates/></li>
</xsl:template>
</xsl:stylesheet>