xpath conditional select, 'tr' having numbers of 'td' > 2 - xpath

While this seems correct xpath (?), it doesn't match in firefox49/firebug nor chrome dev tools 53.0.2785.116
//table[#id="foobar"]/tbody/tr[count("td") > 2]
I try to select all tr having a count() of td > 2

count() function expects a node-set as an argument. Don't put the td into quotes:
//table[#id="foobar"]/tbody/tr[count(td) > 2]

Related

XPATH - how to combine AND / OR

I have the following XPATH expression:
/prod[price/buynow[1] > 19 and text/desc[1][not(contains(.,"bier"))] or text/desc[1][not(contains(.,"kalender"))] or text/desc[1][not(contains(.,"ballon"))]]
I need the first part ( > 19) to be true for all data, whereas the following conditions can be OR.
You can use
expression and (expression or expression)
Here is working example

How to select tr elements that have more than 4 children with XPath?

The XPath expression root.xpath('//table//tr') can get all the tr elements in root.
Now I want to select all tr that have more than 4 children. How to write the expression?
I have tried //table/tr[count(child::)>4] and failed.
You are almost there, try this :
//table/tr[count(child::*)>4]
or simply :
//table/tr[count(*)>4]

Xpath with htmlagilitypack

I am try to select the "string b" text node using XPath with the HtmlAgilliyPack.
<div>
string a<br/>
string b<br/>
string c<br/>
</div>
I am not sure how to select the text?
This won't work //div/text(1)
Anybody has some suggestions?
There are two problems with your expression:
XPath starts counting at 1, so you want the second text node
text() is a node filter which does not accept arguments. If you want to limit to the second text node, use the predicate [position() = 2] or the short version [2].
Use this expression:
//div/text()[2]
Selecting text nodes can include some hassles, chopping leading and trailing whitespace and omitting whitespace-only text nodes is implementation-dependent.
Try:
//div/br[1]/following-sibling::text()[1]'
The direct following text after the first br.

XPath 2.0:reference earlier context in another part of the XPath expression

in an XPath I would like to focus on certain elements and analyse them:
...
<field>aaa</field>
...
<field>bbb</field>
...
<field>aaa (1)</field>
...
<field>aaa (2)</field>
...
<field>ccc</field>
...
<field>ddd (7)</field>
I want to find the elements who's text content (apart from a possible enumeration, are unique. In the aboce example that would be bbb, ccc and ddd.
The following XPath gives me the unique values:
distinct-values(//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))
Now I would like to extent that and perform another XPath on all the distinct values, that would be to count how many field start with either of them and retreive the ones who's count is bigger than 1.
These could be a field content that is equal to that particular value, or it starts witrh that value and is followed by " (". The problem is that in the second part of that XPath I would have refer to the context of that part itself and to the former context at the same time.
In the following XPath I will - instead of using "." as the context- use c_outer and c_inner:
distinct-values(//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))[count(//field[(c_inner = c_outer) or starts-with(c_inner, concat(c_outer, ' ('))]) > 1]
I can't use "." for both for obvious reasons. But how could I reference a particular, or the current distinct value from the outer expression within the inner expression?
Would that even be possible?
XQuery can do it e.g.
for $s
in distinct-values(
//field[matches(normalize-space(.), ' \([0-9]\)$')]/substring-before(., '(')))
where count(//field[(. = $s) or starts-with(., concat($s, ' ('))]) > 1
return $s

selecting nth match of a regular expression

I have a string in the format of 00:00:00:0000. I want to capture the last : i.e before 0000 and change it to another character. How do I select only that one : ?. I was wondering if there is a way of selecting a character preceeded by other regexp match(as there is a way of selecting characters followed by a regexpr match with (?=pattern) or a way of counting the matched : and only selecting let's say the 4th match. I am using ruby 1.8.7 implementantion of regular expressions. How do I do this?
You can use a look ahead assertion like this:
/:(?=[^:]*$)/
You can select the last match
ruby-1.9.2-p290 :003 > "0:00:00:0000".gsub(/(:)([^:]+)$/, "x\\2")
=> "0:00:00x0000"
Another way is to use String#[]= method:
str = "0:00:00:0000"
str[/(:)[^:]+$/, 1] = '*'
str # => "0:00:00*0000"

Resources