Here is one approach. You define a key to group your items you are looking to remove. I think you are grouping by the @id attribute of the element, together with the @id attribute of the two parent nodes
<xsl:key
name="items"
match="*[@method != '']" use="concat(@id, '|', ../@id, '|', ../../@id)" />
Next, you could have a template to match your @method=’create’ items where there are two elements in the key, and the other item is a @method=’delete’
<xsl:template match="*
[@method = 'create']
[count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2]
[key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'delete']]" />
You would also need a template to match the other @method=’delete’ in a similar manner.
Here is the full XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="items" match="*[@method != '']" use="concat(@id, '|', ../@id, '|', ../../@id)" />
<xsl:template match="*[@method = 'create'][count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2][key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'delete']]" />
<xsl:template match="*[@method = 'delete'][count(key('items', concat(@id, '|', ../@id, '|', ../../@id))) = 2][key('items', concat(@id, '|', ../@id, '|', ../../@id))[@method = 'create']]" />
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
When applied to your sample XML, the following is output
<root>
<sector>
<nodeA id="a">
<section id="i"/>
</nodeA>
<nodeA id="b">
<cell id="ii"/>
<cell id="ii"/>
</nodeA>
<nodeB id="i">
<cell id="ii">
<item3 id="1" method="create">
<child>b</child>
</item3>
</cell>
<cell id="ii">
<item3 id="1" method="delete"/>
<item3 id="1" method="create">
<otherchild>a</otherchild>
</item3>
</cell>
</nodeB>
</sector>
</root>
0
solved How to do this xml elimination based on node attribute positions using XSLT ? [closed]