MokiNex
MokiNex

Reputation: 879

How to use XPath contains()

My XML

<r>
  <ul>
    <li>ModelA</li>
    <bi>Foo</bi>
  </ul>
  <ul>
    <li>ModelB</li>
    <bi>boo</bi>
  </ul>
</r>

For specific node value I want to extract the value of the successor node.

Example when li = ModelA get the value of bi which is Foo

My Xpath : //ul[li[contains(.,'ModelA')]]

Upvotes: 0

Views: 232

Answers (4)

Jack Fleeting
Jack Fleeting

Reputation: 24930

If I understand your question correctly, this may do the trick:

//ul/li[contains(.,'ModelA')]/following-sibling::bi

Edit: Following @Thomas Weller's correct observation in the comments below, here's a simple explanation of this xpath expression:

Your target <bi> is a child of the target <ul> which itself has another child (<li>, hence, the //ul/li part), which itself (i.e., the <li>) contains the text li[contains(.,'ModelA')]). Since both <li> and <bi>, as children of the same <ul>,are siblings, once that <li> is located, the next stop is to locate its sibling <bi> (hence the final /following-sibling::bi).

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163322

Why do you want to use contains() for this? Just use "=".

//ul/li[. = 'ModelA')]/following-sibling::bi

The contains() function is needed only if you want to match a substring, for example if you also want to match a node whose value is SuperModelA2

Upvotes: 0

kjhughes
kjhughes

Reputation: 111541

If it needn't be a successor – if sibling suffices – just add the bi to the end of your XPath:

//ul[li[contains(.,'ModelA')]]/bi

will select all bi elements with li siblings that have a string value that contains a 'ModelA substring. If you actually want an equality rather than a substring test, you can simplify this to

//ul[li='ModelA']/bi

See also What does contains() do in XPath?

Upvotes: 0

Thomas Weller
Thomas Weller

Reputation: 59289

Your XPath does not contain bi, so it will not select a bi-Node.

Start with

//ul/bi

which selects the bi-node. Now add the conditions in square brackets. The first condition is "the parent node has a li-subnode:

//ul/bi[../li]

The second condition is: that li-node contains text:

//ul/bi[../li[contains(.,'ModelA')]]

However, this might not do what you want in case of multiple bi nodes. If you really need the next bi node only, the answer of @Jack Fleeting is probably best.

Upvotes: 1

Related Questions