Closed jozip closed 14 years ago
It's just something left over from Watir, I guess. Any reason you can't use the normal :xpath selector though?
browser.div(:id => "foo").span(:xpath => "...")
The xpath selector forms a condition, right? If I'm not mistaken, the selector in the snippet would yield a specific span that matches the condition. What I mean is that I'd like to be able to use xpath on a subset of a page, and thus making that subset the root in a subsequent search. (HtmlUnit's HtmlPage and HtmlElement both inherit DomNode, so it shouldn't be very dramatic.)
I don't see what use case you have that isn't covered by the existing API. Could you explain in more detail (i.e. with code examples)?
element_by_xpath[s] is being considered for removal in future versions, so I'm interested to hear why you think it's needed.
I agree with toki and would also like to see a method that works like Element#search in Nokogiri and Hpricot. It would allow me to write code on this form:
tables = browser.elements_by_xpath("/html/body/table")
data = table[0].elements_by_xpath("tr").map do |tr|
tr.elements_by_xpath("td").map(&:text)
end
AFAIK, it's not possible to do this with the current Celerity API but I would love to be proven wrong.
Oh, the functionality covers it as far as I know. The thing is that I don't understand what the :xpath selector means. Is it the xpath forming a condition for the spans? Is it an expression for selecting the sub-elements of a specific span? In the first case, you lose a lot of the expressive power of xpaths. The second case would be what I'm looking for, but having the xpath as a selector seems kind of awkward. Edit: Qerub said it nicely what I'm aiming at.
In my example, you choose a "subdocument" (the div) and then find a span matching the xpath provided. So e.g., for
<div id=container>
<span class=greeting>Hello</span>, <span class=user>toki</span>.
</div>
browser.div(:id => "container).span(:xpath => ".//span[text()='toki']").class_name #=> "user"
Not the best example maybe, but that's how it works.
I'm sorry if I'm being difficult, but I'm looking to slim down the API rather than grow it. Qerub's example could be done like this, using the actual API:
browser.table.rows.map do |row|
row.cells.map(&:text)
end
or even simpler:
browser.table.to_a
browser.table.elements(:xpath => "//tr").map do |tr|
tr.elements(:xpath => "//td").map(&:text)
end
The reason I would like good support for XPath queries is that I find them very handy for handling complex documents. browser.table.rows[0].cells
is really nice, but sometimes the queries are more like /html/body/table/tr/td/form/div[@class=...]/table/tr[...]/td[2]/div[4]/table/tr/*/span
* and in those cases I find XPath's expressive power hard to beat. Another good point is that many other tools use XPath and I find it practical to just extract a query from, say, Firebug and drop it directly in a Celerity script.
elements(:xpath => ...)
will definitely add this functionality for me, so I would consider this feature request fulfilled.
I'm sorry if I'm being difficult, but I'm looking to slim down the API rather than grow it.
I think that's a great goal, so need to be sorry. :)
* "Real world" HTML made by "other people" can really suck...
Cool, thanks!
"Real world" HTML made by "other people" can really suck...
No kidding.
[...] If you really want to use XPaths, as part of the upcoming changes you'll be able to do:
browser.table.elements(:xpath => "//tr").map do |tr| tr.elements(:xpath => "//td").map(&:text) end
What's the status of this change?
Status is still the same. Bringing Celerity to Watir 2 compatibility is not something I'm prioritizing at the moment. Feel free to implement this :)
For reference: I settled with adding Container#elements_by_xpath
instead, even though Browser#elements_by_xpath
is considered for removal because it was easier.
If anybody else is interested, the patch is at qerub@650928b056d7551ad57c2811f146ed0b566b8005.
It would be nice to be able to use xpath on a subset of a page. Any specific reason why this isn't included?