I am trying to transform horrific XML with embedded richtext formatting into HTML. I found a way to identify the start of a bulleted list, based on an attribute in a previous-sibling node, but I can't figure out how to end the bulleted list. The problem is that the attributes of each block of text are defined either in a previous-sibling node or in the first paragraph in the series.
I have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<item>
<richtext>
<pardef/>
<par def='20'><run>This is the first </run><run>paragraph of the preamble.</run></par>
<par><run>This is the second paragraph of the </run><run>preamble.</run></par>
<pardef list='bullet'/>
<par def='21'><run>This is the </run><run>first bullet.</run></par>
<par><run>This is the second </run><run>bullet.</run></par>
<par def='20'><run>This is the first </run><run>paragraph of the conclusion.</run></par>
<par><run>This is the second paragraph of the </run><run>conclusion.</run></par>
</richtext>
</item>
</document>
I want the following output:
<p>This is the first paragraph of the preamble.</p>
<p>This is the second paragraph of the preamble.</p>
<ul>
<li>This is the first bullet.</li>
<li>This is the second bullet.</li>
</ul>
<p>This is the first paragraph of the conclusion.</p>
<p>This is the second paragraph of the conclusion.</p>
I have the following XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:key name="key-for-par" match="document/item/richtext/par" use="generate-id(preceding-sibling::pardef[1])"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="document/item/richtext/pardef" />
</xsl:template>
<xsl:template match="pardef[@list = 'bullet']">
<ul>
<xsl:for-each select="key('key-for-par', generate-id(.))">
<li>
<xsl:value-of select="run" separator=""/>
</li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template match="pardef[not(@list)]">
<xsl:for-each select="key('key-for-par', generate-id(.))">
<p>
<xsl:value-of select="run" separator=""/>
</p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>