7

I'm trying to test if an attribute on an ancestor of an element not equal a string.

Here is my XML...

<aaa att="xyz">
<bbb>
<ccc/>
</bbb>
</aaa>
<aaa att="mno">
<bbb>
<ccc/>
</bbb>
</aaa>

If I'm acting on element ccc, I'm trying to test that its grandparent aaa @att doesn't equal "xyz".

I currently have this...

ancestor::aaa[not(contains(@att, 'xyz'))]

Thanks!

Jeff
  • 877
  • 2
  • 11
  • 17

1 Answers1

16

Assuming that by saying an ancestor of an element you're referring to an element with child elements, this XPath expression should do:

//*[*/ccc][@att != 'xyz']

It selects

  1. all nodes
  2. that have at least one <ccc> grandchild node
  3. and that have an att attribute whose value is not xyz.

Update: Restricted test to grandparents of <ccc>.

Update 2: Adapted to your revised question:

//ccc[../parent::aaa/@att != 'xyz']

Selects

  1. all <ccc> elements
  2. that have a grandparent <aaa> with its attribute att set to a value that is not xyz
O. R. Mapper
  • 20,083
  • 9
  • 69
  • 114
  • Thanks for the reply. However, I'm looking to test only on the aaa that is the grandparent of ccc. From you explanation, this tests across all aaa nodes in the document. – Jeff Jun 21 '12 at 20:22
  • @Jeff: This didn't get quite clear from your question; I've updated my response now. – O. R. Mapper Jun 21 '12 at 20:25
  • @Jeff: I've added an alternative solution to demonstrate how to actually have the `` element as the resulting node, as now stated in your question. – O. R. Mapper Jun 21 '12 at 20:50