Re: [xsl] Handling mixed content elements

Subject: Re: [xsl] Handling mixed content elements
From: Bill Humphries <bill@xxxxxxxxx>
Date: Fri, 6 May 2005 00:50:32 -0700
On May 5, 2005, at 11:41 PM, aspsa wrote:

In the source XML document, each paragraph may contain any number of <bold>
and <italic> tags in any order. How can I modify the "paragraph" template to
account for this?

Don't worry, you have to train yourself to think differently when writing XSLT.


Your paragraph template's trying to do too much; instead, let XSLT do the work for you:

<xsl:template match="paragraph">
    <p><xsl:apply-templates /></p>
</xsl:template>

I've rewritten the paragraph template to write the p element to the output, and apply-templates to everything under paragraph instead of the xsl:if.

Then you move the rules for bold and italic into their own templates.

<xsl:template match="bold">
    <strong><xsl:apply-templates /></strong>
</xsl:template>

<xsl:template match="italic">
    <em><xsl:apply-templates /></em>
</xsl:template>

How to describe this: the paragraph template says "I know how to handle paragraph tags! I don't know about others, so I'll pass along all the children of paragraph and let other templates have a shot at them."

The bold and italic templates work in the same way, if there's a bold or italic element in the source document, they set up the appropriate elements in the output and pass along anything inside them for other templates to handle.

Your original template caught the first instance of bold, italic, and the text node, but didn't do further processing.

Now it doesn't matter how many bold and italic elements you have in the paragraph.

Also, note that this set-up catches <bold><italic>something</italic></ bold> and visa versa.

I didn't have to write a template for text nodes, because XSLT has a default template that copies any text nodes to the output.

The complete transform is:

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/ Transform'>

<xsl:template match="paragraph">
    <p><xsl:apply-templates /></p>
</xsl:template>

<xsl:template match="bold">
    <strong><xsl:apply-templates /></strong>
</xsl:template>

<xsl:template match="italic">
    <em><xsl:apply-templates /></em>
</xsl:template>

</xsl:stylesheet>

If you add new elements to the content model for paragraph, you just need to add a template for the new element:

<xsl:template match="underline">
<span style="text-decoration: underline;"><xsl:apply-templates / ></span>
</xsl:template>


Hope that helps.

-- whump

Current Thread