<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dtb="http://www.daisy.org/z3986/2005/dtbook/" version="2.0"> <xsl:template name="addRootStructure"> <xsl:for-each select="node()"> <xsl:variable name="first" select="self::* and count(preceding-sibling::node())=count(preceding-sibling::text()[normalize-space()=''])"/> <xsl:variable name="last" select="self::* and count(following-sibling::node())=count(following-sibling::text()[normalize-space()=''])"/> <xsl:call-template name="insertLevel"> <xsl:with-param name="first" select="$first"/> <xsl:with-param name="last" select="$last"/> <xsl:with-param name="level" select="1"/> </xsl:call-template> </xsl:for-each> </xsl:template> <xsl:template name="addSubStructure"> <xsl:param name="level"/> <xsl:apply-templates select="node()[ not( self::dtb:*[ number(substring-after(name(), 'h'))>=$level or number(substring-after(name(), 'level'))>=$level ] ) and not( preceding-sibling::*[ self::dtb:*[ number(substring-after(name(), 'h'))>=$level or number(substring-after(name(), 'level'))>=$level ] ] ) ]"/> <xsl:for-each select="node()[ self::dtb:*[ number(substring-after(name(), 'h'))>=$level or number(substring-after(name(), 'level'))>=$level ] or preceding-sibling::*[ self::dtb:*[ number(substring-after(name(), 'h'))>=$level or number(substring-after(name(), 'level'))>=$level ] ] ]"> <xsl:variable name="first" select="not(preceding-sibling::*[ self::dtb:*[ number(substring-after(name(), 'h'))>=$level or number(substring-after(name(), 'level'))>=$level ]])"/> <xsl:variable name="last" select="self::* and count(following-sibling::node())=count(following-sibling::text()[normalize-space()=''])"/> <xsl:call-template name="insertLevel"> <xsl:with-param name="first" select="$first"/> <xsl:with-param name="last" select="$last"/> <xsl:with-param name="level" select="$level"/> </xsl:call-template> </xsl:for-each> </xsl:template> <xsl:template name="insertLevel"> <xsl:param name="first"/> <xsl:param name="last"/> <xsl:param name="level"/> <xsl:choose> <xsl:when test="self::dtb:*[name()=concat('level', $level)]"> <xsl:message terminate="no">Corrected a level</xsl:message> <xsl:if test="not($first) and not(preceding-sibling::*[1][self::dtb:*[name()=concat('level', $level)]])"> <xsl:value-of select="concat('</level', $level, '>')" disable-output-escaping="yes"/> </xsl:if> <xsl:apply-templates select="."/> <xsl:if test="not($last) and not(following-sibling::*[1][self::dtb:*[name()=concat('level', $level)]])"> <xsl:value-of select="concat('<level', $level, '>')" disable-output-escaping="yes"/> </xsl:if> </xsl:when> <xsl:when test="$first"> <xsl:message terminate="no">Corrected a level</xsl:message> <xsl:value-of select="concat('<level', $level, '>')" disable-output-escaping="yes"/> <xsl:apply-templates select="."/> </xsl:when> <xsl:when test="$last"> <xsl:message terminate="no">Corrected a level</xsl:message> <xsl:apply-templates select="."/> <xsl:value-of select="concat('</level', $level, '>')" disable-output-escaping="yes"/> </xsl:when> <xsl:when test="self::dtb:*[name()=concat('h', $level)] and preceding-sibling::dtb:*[number(substring-after(name(), 'h'))>=$level]"> <xsl:if test="not(preceding-sibling::*[1][self::dtb:*[name()=concat('level', $level)]])"> <xsl:value-of select="concat('</level', $level, '><level', $level, '>')" disable-output-escaping="yes"/> <xsl:message terminate="no">Corrected a level</xsl:message> </xsl:if> <xsl:apply-templates select="."/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>