The easiest way to do this is to construct an xpath expression which cross checks against the criteria nodes. For instance:
Step 1: The following will select all nodes that are not in the criteria area (So all nodes that do not have a parent named "criteria")
//*[name(..) != 'criteria']
Step 2: Filter out any nodes that also appear in critera section
//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.))]
Now that last statement will select all the nodes that don't match a criteria node. But you just want sub nodes, so we can modify the selector to only grab elements that are "sub elements" or leaf elements that have no child nodes.
//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.)) and not(*)]
So here is the breakdown of each of our conditionals one more time:
name(..) != 'criteria' -- Limits to nodes that are not in the criteria section
not(name(//criteria/*) = name(.)) -- Limits to nodes that do not have the same name as a node in the criteria section
and not(*) - Limits to nodes that do not have any child nodes (so the leaf nodes that you want.)
So if you were do something like:
<xsl:for-each select="//*[name(..) != 'criteria' and not(name(//criteria/*) = name(.)) and not(*)]">
<xsl:value-of select="name(current())"/> :
</xsl:for-each>
For your above example this would print:
subel1 : subel2
Hope this helps.
Cheers,
Casey