<?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <!-- Start --> <xsl:template match="/"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="subcommand"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="*"/> </xsl:copy> </xsl:template> <xsl:template match="flagset"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="flag[not(@name = preceding-sibling::flag/@name)]"> <xsl:apply-templates select="."/> </xsl:for-each> </xsl:copy> </xsl:template> <xsl:template match="contents"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="*"> <xsl:call-template name="Groupings"> <xsl:with-param name="root" select="."/> </xsl:call-template> </xsl:for-each> </xsl:copy> </xsl:template> <xsl:template match="flag|brace|commands|word|ellipses|or"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="*"/> </xsl:copy> </xsl:template> <xsl:template name="showPath"> <xsl:param name="node"/> <xsl:choose> <xsl:when test="count($node/ancestor::*) > 0"> <xsl:call-template name="showPath"> <xsl:with-param name="node" select="$node/ancestor::*[1]"/> </xsl:call-template> </xsl:when> <xsl:otherwise/> </xsl:choose> <xsl:text>/</xsl:text><xsl:value-of select="name($node)"/> </xsl:template> <xsl:template name="Groupings"> <xsl:param name="root"/> <xsl:for-each select="$root"> <xsl:choose> <!-- const | brace | ellipses | flag | group | word --> <xsl:when test="name()='flag'"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:variable name="end_position"> <xsl:call-template name="flag_end"> <xsl:with-param name="root" select="."/> </xsl:call-template> </xsl:variable> <xsl:for-each select="following-sibling::*"> <xsl:if test="position() < $end_position"> <xsl:choose> <!-- Check to see if we have a set of words. Which looks like { word | word | word } --> <xsl:when test="name()='brace' and ./group/or and count(group/or/*) = count(group/or/word)"> <flag_set> <xsl:for-each select="group/or/word"> <xsl:call-template name="RenameElements"> <xsl:with-param name="root" select="."/> <xsl:with-param name="prefix" select="'flag_'"/> </xsl:call-template> </xsl:for-each> </flag_set> </xsl:when> <xsl:when test="true()"> <xsl:call-template name="RenameElements"> <xsl:with-param name="root" select="."/> <xsl:with-param name="prefix" select="'flag_'"/> </xsl:call-template> </xsl:when> </xsl:choose> </xsl:if> </xsl:for-each> </xsl:copy> </xsl:when> <xsl:when test="name()='word' or name()='brace' or name()='group' or name()='ellipses'"> <xsl:choose> <xsl:when test="not(preceding-sibling::flag)"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="*"> <xsl:call-template name="Groupings"> <xsl:with-param name="root" select="."/> </xsl:call-template> </xsl:for-each> </xsl:copy> </xsl:when> <xsl:otherwise> <!-- We have a preceding flag --> <xsl:variable name="here" select="."/> <xsl:variable name="my_flag" select="preceding-sibling::flag[1]"/> <xsl:variable name="end_position"> <xsl:call-template name="flag_end"> <xsl:with-param name="root" select="$my_flag"/> </xsl:call-template> </xsl:variable> <!-- Copy this element only if it is not part of flag.... --> <!-- If it is part of flag, it has already been copied --> <xsl:for-each select="$my_flag/following-sibling::*"> <xsl:if test="position() >= $end_position and generate-id($here) = generate-id(.)"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="*"> <xsl:call-template name="Groupings"> <xsl:with-param name="root" select="."/> </xsl:call-template> </xsl:for-each> </xsl:copy> </xsl:if> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="name()='ellipses'"> </xsl:when> <xsl:when test="name()='const'"> </xsl:when> <xsl:when test="name()='or' or name()='brace' or name()='group'"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each select="*"> <xsl:call-template name="Groupings"> <xsl:with-param name="root" select="."/> </xsl:call-template> </xsl:for-each> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:message> Error with contents template, got an unexpected element <xsl:value-of select="name()"/> </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> <xsl:template name="flag_end"> <xsl:param name="root"/> <xsl:variable name="flag_ends"> <xsl:for-each select="$root/following-sibling::*"> <xsl:choose> <xsl:when test="name()='ellipses' or name()='word' or name()='const'"> <!-- Do nothing, these could be part of flag --> </xsl:when> <xsl:when test="name()='flag'"> <xsl:value-of select="position()"/> <xsl:text>,</xsl:text> </xsl:when> <xsl:when test="name()='brace' or name()='group'"> <xsl:if test=".//flag"> <xsl:value-of select="position()"/> <xsl:text>,</xsl:text> </xsl:if> </xsl:when> <xsl:otherwise> <xsl:message> Error with contents template, got an unexpected element <xsl:value-of select="name()"/> </xsl:message> </xsl:otherwise> </xsl:choose> <xsl:if test="position()=last()"> <xsl:text>l</xsl:text> <xsl:value-of select="position()+1"/> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:variable name="end_position"> <xsl:choose> <xsl:when test="contains($flag_ends,',')"> <xsl:value-of select="substring-before($flag_ends,',')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="substring-after($flag_ends,'l')"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:value-of select="$end_position"/> </xsl:template> <xsl:template name="RenameElements"> <xsl:param name="root" /> <xsl:param name="prefix" /> <xsl:variable name="newname"> <xsl:value-of select="$prefix"/><xsl:value-of select="name($root)"/> </xsl:variable> <xsl:element name="{$newname}"> <xsl:copy-of select="$root/@*"/> <xsl:for-each select="$root/*"> <xsl:call-template name="RenameElements"> <xsl:with-param name="root" select="."/> <xsl:with-param name="prefix" select="$prefix"/> </xsl:call-template> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>