Reputation: 33
I'd like to parse the HTML inside of a CDATA block for <p>
tags and output each in a separate table row. However I can't quite figure it out and was wondering if someone would be able to help me out?
I've been trying to parse the HTML but am unable to figure out how I can parse it and not simply regard it as character data. I'm pretty sure I'm unable to do this with XSL 1.0, I'm able to use 2.0 if needed.
XML
<XML_FILE>
<NOTE>
<TEXT TITLE="TEST">
<![CDATA[<p>first p tag and <strong>bold</strong></p><p>second p tag and <u>underline</u></p>]]>
</TEXT>
</NOTE>
</XML_FILE>
XSL
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="NOTE">
<div class="tableWrapper">
<table class="body">
<xsl:apply-templates select="TEXT"/>
</table>
</div>
</xsl:template>
<xsl:template match="TEXT">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
Output
<div class="tableWrapper">
<table class="body"><p>first p tag and <strong>bold</strong></p><p>second p tag and <u>underline</u></p></table>
</div>
Desired Output
<div class="tableWrapper">
<table class="body">
<tr><td><p>first p tag and <strong>bold</strong></p></td></tr>
<tr><td><p>second p tag and <u>underline</u></p></td></tr>
</table>
</div>
Final stylesheet that provides desired output
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="html" indent="yes" html-version="5"/>
<xsl:strip-space elements="*"/>
<xsl:template match="XML_FILE">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="NOTE">
<div class="tableWrapper">
<table class="body">
<xsl:apply-templates select="parse-xml-fragment(TEXT)/node()"/>
</table>
</div>
</xsl:template>
<xsl:template match="p">
<tr>
<td>
<xsl:next-match/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Upvotes: 3
Views: 229
Reputation: 163262
XSLT 3.0 has a function parse-xml-fragment()
which will tackle this.
There's nothing equivalent in earlier XSLT versions, though you might find vendor extensions that help you out. Most processor allow you to write your own external functions that you can invoke from your XSLT code, and you could write such a function that passed the CDATA content to an external XML parser for conversion into a tree structure.
Upvotes: 2