Reputation: 830
Having this xml snippet:
<paragraph><bold>Test</bold> - This <italic>word</italic> should be <underline>underlined</underline> according to xml</paragraph>
How can I output this "paragraph" to an HTML one while replacing the used tags with the ones used in HTML?
I've tried this XSLT snippet but it doesn't print the text outside of the nested tags, only the text between bold, italic and underlined.
<xsl:template match="p:paragraph">
<xsl:for-each select="./*">
<xsl:choose>
<xsl:when test="name(.)='bold'">
<xsl:apply-templates select="."/>
</xsl:when>
<xsl:when test="name(.)='italic'">
<xsl:apply-templates select="."/>
</xsl:when>
<xsl:when test="name(.)='underlined'">
<xsl:apply-templates select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./text()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="bold">
<p><b><xsl:value-of select="current()"/></b></p>
</xsl:template>
<xsl:template match="italic">
<p><i><xsl:value-of select="current()"/></i></p>
</xsl:template>
<xsl:template match="underline">
<p><u><xsl:value-of select="current()"/></u></p>
</xsl:template>
How can I do the templates do that the output is as expected?
Thanks in advance
Upvotes: 0
Views: 1116
Reputation: 70638
Your main problem is that ./*
(which could be simplified to just *
) selects only elements, but you want to select text nodes too. So what you can do is change it to this...
<xsl:for-each select="node()">
You would also need to change xsl:otherwise
to this...
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
However, you can simplify the whole XSLT to make use of template matching better. Try this XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes" />
<xsl:template match="paragraph">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="bold">
<b>
<xsl:apply-templates />
</b>
</xsl:template>
<xsl:template match="italic">
<i>
<xsl:apply-templates />
</i>
</xsl:template>
<xsl:template match="underline">
<u>
<xsl:apply-templates />
</u>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
(You would obviously need to adjust this to handle namespaces, as your current XSLT is selecting p:paragraph
which suggests you have namespaces in your XML).
Upvotes: 2