module Nokogiri::CSS

Translate a CSS selector into an XPath 1.0 query

Public Class Methods

xpath_for(selector_list) β†’ Array<String> click to toggle source
xpath_for(selector_list [, prefix:] [, ns:] [, visitor:] [, cache:]) β†’ Array<String>

Translate a CSS selector list to the equivalent XPath expressions.

πŸ’‘ Note that translated queries are cached by default for performance concerns.

⚠ Users should prefer Nokogiri::XML::Searchable#css, which is mixed into all document and node classes, for querying documents with CSS selectors. This method is the underlying mechanism used by XML::Searchable and is provided solely for advanced users to translate CSS selectors to XPath directly.

Also see Nokogiri::XML::Searchable#css for documentation on supported CSS selector features, some extended syntax that Nokogiri supports, and advanced CSS features like pseudo-class functions.

Parameters
  • selector_list (String)

    The CSS selector to be translated into XPath. This is always a String, but that string value may be a selector list (see examples).

Keyword arguments
  • prefix: (String)

    The XPath expression prefix which determines the search context. See Nokogiri::XML::XPath for standard options. Default is XPath::GLOBAL_SEARCH_PREFIX.

  • ns: (Hash<String β‡’ String>, nil)

    Namespaces that are referenced in the query, if any. This is a hash where the keys are the namespace prefix and the values are the namespace URIs. Default is nil indicating an empty set of namespaces.

  • visitor: (Nokogiri::CSS::XPathVisitor)

    Use this XPathVisitor object to transform the CSS AST into XPath expressions. See Nokogiri::CSS::XPathVisitor for more information on some of the complex behavior that can be customized for your document type. Default is Nokogiri::CSS::XPathVisitor.new.

    ⚠ Note that this option is mutually exclusive with prefix and ns. If visitor is provided, prefix and ns must not be present.

  • cache: (Boolean)

    Whether to use the SelectorCache for the translated query to ensure that repeated queries don’t incur the overhead of re-parsing the selector. Default is true.

Returns

(Array<String>) The equivalent set of XPath expressions for selector_list

Example with a simple selector:

Nokogiri::CSS.xpath_for("div") # => ["//div"]

Example with a compound selector:

Nokogiri::CSS.xpath_for("div.xl") # => ["//div[contains(concat(' ',normalize-space(@class),' '),' xl ')]"]

Example with a complex selector:

Nokogiri::CSS.xpath_for("h1 + div") # => ["//h1/following-sibling::*[1]/self::div"]

Example with a selector list:

Nokogiri::CSS.xpath_for("h1, h2, h3") # => ["//h1", "//h2", "//h3"]
# File lib/nokogiri/css.rb, line 83
def xpath_for(
  selector, options = nil,
  prefix: options&.delete(:prefix),
  visitor: options&.delete(:visitor),
  ns: options&.delete(:ns),
  cache: true
)
  unless options.nil?
    warn("Nokogiri::CSS.xpath_for: Passing options as an explicit hash is deprecated. Use keyword arguments instead. This will become an error in a future release.", uplevel: 1, category: :deprecated)
  end

  raise(TypeError, "no implicit conversion of #{selector.inspect} to String") unless selector.respond_to?(:to_str)

  selector = selector.to_str
  raise(Nokogiri::CSS::SyntaxError, "empty CSS selector") if selector.empty?

  if visitor
    raise ArgumentError, "cannot provide both :prefix and :visitor" if prefix
    raise ArgumentError, "cannot provide both :ns and :visitor" if ns
  end

  visitor ||= begin
    visitor_kw = {}
    visitor_kw[:prefix] = prefix if prefix
    visitor_kw[:namespaces] = ns if ns

    Nokogiri::CSS::XPathVisitor.new(**visitor_kw)
  end

  if cache
    key = SelectorCache.key(selector: selector, visitor: visitor)
    SelectorCache[key] ||= Parser.new.xpath_for(selector, visitor)
  else
    Parser.new.xpath_for(selector, visitor)
  end
end