How-To: Preserve embedded XHTML tags during XSLT tranform?

L

Luke Dalessandro

I have some XML data that has mixed content XML tags that embed XHTML
tags, for instance:

<note>Somebody wrote this note in XHTML and wanto to <a
href="link.html" target="_new">link</a> to a particular tag, and was
also pretty sure that they wanted the following
<ul><li>two</li><li>items</li></ul> to appear as a list. To make
matters worse <sarcastic>how could this be worse?</sarcastic>, the
XHTML can be mixed with our own tags.</note>

I am trying to transform this data with an XSLT into oddly formated
XHTML for display (I happen to be doing it server-side, with ASP.NET
2.0). The problem is that I need to preserve all of the embedded XHTML
tags in the XML document, while writing templates for all of our
custom content.

The only thing that I have successfully done so far is to write my own
templates for all of the XHTML tags, that output themselves and
process their children, for instance:

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

There are way too many XHTML tag possibilities for me to handle though
(and I have to deal with all of the possible attributes, and output
them correctly too).

Is there a better way to do this, or if there isn't, does anyone have
an XSLT document that handles all (or most) of the XHTML tags that I
can include? I can force everyone to use namespaces if necessary (ie
<xhtml:b></xhtml:b>).

Desperately seeking help,

Luke Dalessandro
 
D

David Carlisle

If your xhtml really is in xhtml (ie is in the xhtml namespace) then you
can easily match on all the xhtml elements without having to list them

<xsl:template match="h:*" xmlns:h="http://www.w3.org/1999/xhtml">
.....


However I suspect that all you want to do is copy the content of a note
element in to the output as-is, in which case you don't need templates
at all, eg

<xsl:template match="note">
<div>
<xsl:copy-of select="node()"/>
</div>
</xsl:template>


David
 
L

Luke Dalessandro

David,

Thanks for the advice:

I can't use copy-of because of the nesting that is possible in our schema.
Notes may contain custom tags that need their templates applied for output.
If I use copy-of, they won't get transformed.

I'm not sure how to implement the first option. I don't want to write the
templates for all of the xhtml tags, I want to use templates that already
exist, or just copy them while rendering their inner contents with
templates.

I see how that matches the tags, but not how it transforms them correctly.

Thanks,

Luke
 
D

David Carlisle

I see how that matches the tags, but not how it transforms them correctly.

you want to do an identity transform on xhtml but recursively process
its content (which may not be the identity) so:

<xsl:template match="h:*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>


xsl:copy (unlike copy-of) does a "shallow copy" that just generates an
element with the same name as the current node, then you copy any
attributes over then just recursively apply templates which will copy
any child text or xhtml but do whatever it does with your own specific
elements that have their own templates.

the above assumes xsl: and h: bound to appropriate namespaces of course.

David
 
L

Luke Dalessandro

Perfect!

Thanks

David Carlisle said:
you want to do an identity transform on xhtml but recursively process
its content (which may not be the identity) so:

<xsl:template match="h:*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>


xsl:copy (unlike copy-of) does a "shallow copy" that just generates an
element with the same name as the current node, then you copy any
attributes over then just recursively apply templates which will copy
any child text or xhtml but do whatever it does with your own specific
elements that have their own templates.

the above assumes xsl: and h: bound to appropriate namespaces of course.

David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top