xpath: find element that contains text x and not y

  • Last Update :
  • Techknowledgy :

Please try following XPath and let me know if any errors occurs:

//*[contains(text(), "Chocolate")][not(contains(text(), "Dark"))]

For elements containing the word 'Chocolate' but not 'Dark', use:

//*[contains(text(), 'Chocolate') and not(contains(text(), 'Dark'))]

For just the text of the elements, use:

//text()[contains(., 'Chocolate') and not(contains(., 'Dark'))]

Given the following XML:

<doc>
   <e>Dark Chocolate</e>
   <e>Chocolate</e>
</doc>

The second expression results in:

> xpath - e "//text()[contains(., 'Chocolate') and not(contains(., 'Dark'))]"
test.xml
Chocolate

Suggestion : 2

Xpath doesn’t have the “check if part of space-separated list” operator, so this is the workaround (source).,Separate your steps with /. Use two (//) if you don’t want to select direct children.,A step may have an element name (div) and predicates ([...]). Both are optional. They can also be these other things:,Steps of an expression are separated by /, usually used to pick child nodes. That’s not always true: you can specify a different “axis” with ::.

Browser console

$x("//div")

Class check

//div[contains(concat(' ',normalize-space(@class),' '),' foobar ')]

Steps

//div
//div[@name='box']
//[@id='link']

Predicates

//div[true()]
//div[@class="head"]
//div[@class="head"][@id="top"]

Operators

# Comparison
//a[@id = "xyz"]
//a[@id != "xyz"]
//a[@price > 25]

Suggestion : 3

17.3.12 array:for-each

fn: xml - to - json($input, map {
   'indent': true()
})
let $para :=
<para>In a hole in the ground there lived a <term author="Tolkien">hobbit</term>.</para>
op: operation(xs: int, xs: double) => op: operation(xs: double, xs: double)
op: operation(fenceHeight, xs: integer) => op: operation(xs: integer, xs: integer)
fn: abs($N * $arg2) le fn: abs($arg1)
and fn: compare($N * $arg2, 0) eq fn: compare($arg1, 0).
1 º 2 º 3 º 4 º...

Suggestion : 4

If you want to find text that spans multiple children/text nodes, then you can use . instead of text(). . refers to the entire text content of the element and it's children.,And to more clearly see the entire text content of an element, one can use the string function:,To find an element containing specific text, you can use the contains function. The following expression will return the <example> element:,will return the <element>hello</element> element, but not the <another> element. This is because the <another> element contains whitespace surrounding the hello text.

Imagine the following XML:

<root>
   <element>hello</element>
   <another>
      hello
   </another>
   <example>Hello, <nested> I am an example </nested>.</example>
</root>

The following XPath expression:

//*[text() = 'hello']

To retrieve both <element> and <another>, one could use:

//*[normalize-space(text()) = 'hello']

To find an element containing specific text, you can use the contains function. The following expression will return the <example> element:

//example[contains(text(), 'Hello')]

If you want to find text that spans multiple children/text nodes, then you can use . instead of text(). . refers to the entire text content of the element and it's children.

//example[. = 'Hello,  I am an example .']