Hi All,
I have a flat XML structure like this that I need to add hierarchy to.
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<h1>Heading 1</h1>
<para>Some text under heading 1</para>
<para>Some text under heading 1</para>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<para>Some text under heading 1</para>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<para>Some text under heading 3</para>
<para>Some text under heading 3</para>
<h4>Heading 4</h4>
<para>Some text under heading 4</para>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
</doc>
My current stylesheet gives me this, which is what I want:
<?xml version="1.0" encoding="UTF-8"?>
<concept id="d1e3">
<title>Heading 1</title>
<conbody>
<para>Some text under heading 1</para>
<para>Some text under heading 1</para>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<li>list item under heading 1</li>
<para>Some text under heading 1</para>
<concept id="d1e28">
<title>Heading 2</title>
<conbody>
<concept id="d1e31">
<title>Heading 3</title>
<conbody>
<para>Some text under heading 3</para>
<para>Some text under heading 3</para>
<concept id="d1e41">
<title>Heading 4</title>
<conbody>
<para>Some text under heading 4</para>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
<li>list item under heading 4</li>
</conbody>
</concept>
</conbody>
</concept>
</conbody>
</concept>
</conbody>
</concept>
However, I have <li> elements that need to be grouped as well; they can
appear just about anywhere in the source XML. Is there a generalized
solution where I can address grouping anywhere in my structure? Here is my
current stylesheet.
<?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"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0" expand-text="yes">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="doc">
<xsl:for-each-group select="*" group-starting-with="h1">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="h1" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
<xsl:when test="not(following-sibling::*[1][self::title])">
<conbody>
<xsl:for-each-group select="current-group() except
." group-starting-with="h2">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</conbody>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="current-group() except ."
group-starting-with="h2">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</concept>
</xsl:template>
<xsl:template match="h2" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
<xsl:when
test="not(following-sibling::*[1][self::heading3])">
<conbody>
<xsl:for-each-group select="current-group() except
." group-starting-with="h3">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</conbody>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="current-group() except ."
group-starting-with="h3">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</concept>
</xsl:template>
<xsl:template match="h3" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<xsl:choose>
<xsl:when test="not(following-sibling::*[1][self::h4])">
<conbody>
<xsl:for-each-group select="current-group() except
." group-starting-with="h4">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</conbody>
</xsl:when>
<xsl:otherwise>
<xsl:for-each-group select="current-group() except ."
group-starting-with="h4">
<xsl:apply-templates select="." mode="group"/>
</xsl:for-each-group>
</xsl:otherwise>
</xsl:choose>
</concept>
</xsl:template>
<xsl:template match="h4" mode="group">
<concept id="{generate-id()}">
<title><xsl:apply-templates/></title>
<conbody>
<xsl:apply-templates select="current-group() except ."/>
</conbody>
</concept>
</xsl:template>
<xsl:template match="*" mode="group">
<xsl:apply-templates select="current-group()"/>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
</xsl:stylesheet>
Thank you for your help.
Rick Quatro
|