Skip to content

teamcapybara/xpath

This branch is 3 commits ahead of master.

Folders and files

NameName
Last commit message
Last commit date

Latest commit

c26913a · Jun 10, 2023
Jun 10, 2023
Jun 10, 2023
Jun 10, 2023
Dec 30, 2017
Jun 10, 2023
Oct 15, 2018
Oct 15, 2018
Oct 27, 2016
May 25, 2017
Oct 15, 2018
Mar 16, 2013
Jun 10, 2023

Repository files navigation

XPath

XPath is a Ruby DSL around a subset of XPath 1.0. Its primary purpose is to facilitate writing complex XPath queries from Ruby code.

Gem Version Build Status

Generating expressions

To create quick, one-off expressions, XPath.generate can be used:

XPath.generate { |x| x.descendant(:ul)[x.attr(:id) == 'foo'] }

You can also call expression methods directly on the XPath module:

XPath.descendant(:ul)[XPath.attr(:id) == 'foo']

However for more complex expressions, it is probably more convenient to include the XPath module into your own class or module:

module MyXPaths
  include XPath

  def foo_ul
    descendant(:ul)[attr(:id) == 'foo']
  end

  def password_field(id)
    descendant(:input)[attr(:type) == 'password'][attr(:id) == id]
  end
end

Both ways return an XPath::Expression instance, which can be further modified. To convert the expression to a string, just call #to_s on it. All available expressions are defined in XPath::DSL.

String, Hashes and Symbols

When you send a string as an argument to any XPath function, XPath assumes this to be a string literal. On the other hand if you send in Symbol, XPath assumes this to be an XPath literal. Thus the following two statements are not equivalent:

XPath.descendant(:p)[XPath.attr(:id) == 'foo']
XPath.descendant(:p)[XPath.attr(:id) == :foo]

These are the XPath expressions that these would be translated to:

.//p[@id = 'foo']
.//p[@id = foo]

The second expression would match any p tag whose id attribute matches a 'foo' tag it contains. Most likely this is not what you want.

In fact anything other than a String is treated as a literal. Thus the following works as expected:

XPath.descendant(:p)[1]

Keep in mind that XPath is 1-indexed and not 0-indexed like most other programming languages, including Ruby.

License

See LICENSE.