Это преобразование :
<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:key name="kPreceding" match="product" use=
"generate-id(
(self::product|following-sibling::product)
[@defective='yes'][1]
)"/>
<xsl:template match="product[last()]">
<xsl:copy-of select="key('kPreceding', generate-id())"/>
</xsl:template>
</xsl:stylesheet>
при применении к предоставленному XML (исправлено, чтобы быть правильно сформированным !!!):
<t>
<product id="456"/>
<product id="457" defective="yes"/>
<product id="458"/>
<product id="459"/>
<product id="460" defective="yes"/>
</t>
дает желаемый, правильный результат :
<product id="458"/>
<product id="459"/>
<product id="460" defective="yes"/>
Объяснение
Использование ключа для индексации любого продукта по generate-id()
первого последовавшего брата product
, который неисправен (или сам, если этот product
сам по себе неисправен).