xslt - Transforming XML mixed nodes with disable-output-escaping -
variations on question have been posted, couldn't find address base case. thought have canonical answer simplest version of problem. question assumes xslt 1.0.
i have xml document contains mixed nodes, e.g.:
<paragraph> text <bold>bold</bold> , <italic>italicized.</italic> </paragraph>
i typically use transformation looks this:
<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="paragraph"> <p><xsl:apply-templates/></p> </xsl:template>
which works great until want use disable-output-escaping="yes", attribute of xsl:value-of. there way select text-portion of mixed node can apply value-of independent of embedded nodes?
this, of course, doesn't work because lose child nodes:
<xsl:template match="paragraph"> <p><xsl:value-of select="." disable-output-escaping="yes"/></p> </xsl:template>
i know fact trying represents inherent problem in way handling xml, of xml being fairly-naively generated (trusted) user input, , trying avoid lot of processing code between xml->xslt->html form (if possible).
if understand right, want text nodes come out literal text (disable-output-escaping="yes"
), rest of transformation should work (<bold>
<b>
etc.)
template modes can help:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" > <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="yes" /> <xsl:template match="paragraph"> <p> <xsl:apply-templates mode="literal" /> </p> </xsl:template> <!-- literal templates (invoked in literal mode) --> <xsl:template match="bold" mode="literal"> <b><xsl:apply-templates mode="literal"/></b> </xsl:template> <xsl:template match="italic" mode="literal"> <i><xsl:apply-templates mode="literal"/></i> </xsl:template> <xsl:template match="text()" mode="literal"> <xsl:value-of select="." disable-output-escaping="yes" /> </xsl:template> <!-- normal templates (invoked when don't use template mode) --> <xsl:template match="bold"> <b><xsl:apply-templates /></b> </xsl:template> <xsl:template match="italic"> <i><xsl:apply-templates /></i> </xsl:template> </xsl:stylesheet>
Comments
Post a Comment