I. XSLT 2.0 Solution :
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match= "section[some $t in $pInterests/*/@topic satisfies not($t = current()/@*[. eq 'no']/name()) ] "> <section><xsl:apply-templates/></section> </xsl:template> <xsl:template match="section"/> </xsl:stylesheet>
when applied to the provided XML document :
<manual> <section>A: This is relevant for every type</section> <section t600="no" t800="no">B: This is relevant only for the 737-400</section> <section t800="no">C: This is relevant for 737-400 and 737-600</section> <section t400="no">D: This is relevant for 737-600 and 737-800</section> </manual>
creates the desired, correct result :
<manual> <section>A: This is relevant for every type</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual>
If we replace the current parameter in the transformation :
<xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param>
from
<xsl:param name="pInterests"> <interest topic="t400"/> <interest topic="t600"/> </xsl:param>
and again apply the modified transformation in the same XML document, we will also get the desired and correct result :
<manual> <section>A: This is relevant for every type</section> <section>B: This is relevant only for the 737-400</section> <section>C: This is relevant for 737-400 and 737-600</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual>
II. XSLT 1.0 Solution :
<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:param name="pInterests"> <interest topic="t800"/> </xsl:param> <xsl:key name="kSectionTypeAttrByName" match="section/@*" use="concat(generate-id(..),'|', name())"/> <xsl:variable name="vInterests" select= "document('')/*/xsl:param[@name='pInterests']/*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="section"> <xsl:variable name="vSec" select="."/> <xsl:variable name="vHasInterest"> <xsl:for-each select="$vInterests/@topic"> <xsl:variable name="vTopic" select="."/> <xsl:for-each select= "$vSec[not(key('kSectionTypeAttrByName', concat(generate-id(),'|', $vTopic) ) = 'no' ) ]"> <xsl:text>1</xsl:text> </xsl:for-each> </xsl:for-each> </xsl:variable> <xsl:if test="string($vHasInterest)"> <section><xsl:apply-templates/></section> </xsl:if> </xsl:template> </xsl:stylesheet>
when applied to the provided XML document :
<manual> <section>A: This is relevant for every type</section> <section t600="no" t800="no">B: This is relevant only for the 737-400</section> <section t800="no">C: This is relevant for 737-400 and 737-600</section> <section t400="no">D: This is relevant for 737-600 and 737-800</section> </manual>
creates the desired, correct result :
<manual> <section>A: This is relevant for every type</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual>
If we replace the current parameter in the transformation :
<xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param>
from
<xsl:param name="pInterests"> <interest topic="t400"/> <interest topic="t600"/> </xsl:param>
and again apply the modified transformation in the same XML document, we will also get the desired and correct result :
<manual> <section>A: This is relevant for every type</section> <section>B: This is relevant only for the 737-400</section> <section>C: This is relevant for 737-400 and 737-600</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual>