Here is a complete solution that overrides the rule / identity template for any story element that does not have a child group element:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="story[not(group)]"> <xsl:copy> <xsl:apply-templates select="@*"/> <group> <sectionhead /> </group> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <xsl:template match="group[not(sectionhead)]"> <xsl:copy> <xsl:apply-templates select="@*"/> <sectionhead /> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
when it applies to the provided XML document (without group ):
<story> <text> <lines> <l1>line</l1> </lines> </text> </story>
the desired, correct result is output:
<story> <group> <sectionhead/> </group> <text> <lines> <l1>line</l1> </lines> </text> </story>
when applied to the first XML document (with group that does not have a sectionhead ):
<story> <group> <overhead> <l1>overhead</l1> </overhead> <headline> <l1>headline</l1> </headline> </group> <text> <lines> <l1>line</l1> </lines> </text> </story>
the same conversion again leads to the desired correct result:
<story> <group> <sectionhead/> <overhead> <l1>overhead</l1> </overhead> <headline> <l1>headline</l1> </headline> </group> <text> <lines> <l1>line</l1> </lines> </text> </story>
source share