I. Решение XSLT 2.0 :
<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>
при применении к предоставленному документу XML :
<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>
дает желаемый, правильный результат :
<manual>
<section>A: This is relevant for every type</section>
<section>D: This is relevant for 737-600 and 737-800</section>
</manual>
Если заменить в преобразовании текущий параметр :
<xsl:param name="pInterests">
<interest topic="t800"/>
</xsl:param>
с
<xsl:param name="pInterests">
<interest topic="t400"/>
<interest topic="t600"/>
</xsl:param>
и снова примените измененное преобразование к тому же XML-документу, мы также получим требуемый и правильный результат :
<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 :
<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>
при применении к предоставленному документу XML :
<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>
дает желаемый, правильный результат :
<manual>
<section>A: This is relevant for every type</section>
<section>D: This is relevant for 737-600 and 737-800</section>
</manual>
Если заменить в преобразовании текущий параметр :
<xsl:param name="pInterests">
<interest topic="t800"/>
</xsl:param>
с
<xsl:param name="pInterests">
<interest topic="t400"/>
<interest topic="t600"/>
</xsl:param>
и снова примените измененное преобразование к тому же XML-документу, мы также получим требуемый и правильный результат :
<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>