EDIT: For some reason I thought this was an XSLT question. Here's one way you could do this with just XPath:
//transaction[(@products = preceding-sibling::transaction/@products or
@products = following-sibling::transaction/@products)]
Here's how you could query all such distinct elements (requires XPath 2.0):
//transaction[(@products = preceding-sibling::transaction/@products or
@products = following-sibling::transaction/@products) and
not(concat(@products, '+', @sumPrice) =
preceding-sibling::transaction/concat(@products, '+', @sumPrice))]
Here's one way to do this with XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kTrans" match="transaction" use="@products" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<n>
<xsl:apply-templates select="transaction[key('kTrans', @products)[2]]" />
</n>
</xsl:template>
</xsl:stylesheet>
When run on your sample input, the result is:
<n>
<transaction products="salmon mooseMeat" sumPrice="365" />
<transaction products="salmon mooseMeat" sumPrice="300" />
</n>
Note that I've wrapped the result in an n
element because it's not valid to have XML with more than one root element.