Module: Leptris::XML::Searchable

Included in:
Document, Node, NodeSet
Defined in:
lib/leptris/xml/searchable.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.wrap_xpath_result(document, result_ptr) ⇒ Object

Shared by Searchable#xpath and Leptris::XML::XPath (compiled expressions): wraps a raw XPathResult pointer into the Ruby-typed result and frees the C handle.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/leptris/xml/searchable.rb', line 88

def self.wrap_xpath_result(document, result_ptr)
  type = Leptris::XML::FFI.leptris_xpath_result_type(result_ptr)
  case type
  when Leptris::XML::FFI::XPATH_NODESET
    Leptris::XML::NodeSet.send(:from_result, document, result_ptr)
  when Leptris::XML::FFI::XPATH_BOOLEAN
    v = Leptris::XML::FFI.leptris_xpath_result_boolean(result_ptr) != 0
    Leptris::XML::FFI.leptris_xpath_result_free(result_ptr)
    v
  when Leptris::XML::FFI::XPATH_NUMBER
    v = Leptris::XML::FFI.leptris_xpath_result_number(result_ptr)
    Leptris::XML::FFI.leptris_xpath_result_free(result_ptr)
    v
  when Leptris::XML::FFI::XPATH_STRING
    str_ptr = Leptris::XML::FFI.leptris_xpath_result_string(result_ptr)
    v = Leptris::XML::FFI.read_owned_string(str_ptr)
    Leptris::XML::FFI.leptris_xpath_result_free(result_ptr)
    v
  else
    Leptris::XML::FFI.leptris_xpath_result_free(result_ptr)
    raise Leptris::XML::XPathError, "unknown xpath result type #{type}"
  end
end

Instance Method Details

#at(*args) ⇒ Object Also known as: %



37
38
39
40
# File 'lib/leptris/xml/searchable.rb', line 37

def at(*args)
  result = search(*args)
  result.is_a?(Leptris::XML::NodeSet) ? result.first : result
end

#at_css(*args) ⇒ Object



51
52
53
54
# File 'lib/leptris/xml/searchable.rb', line 51

def at_css(*args)
  result = css(*args)
  result.is_a?(Leptris::XML::NodeSet) ? result.first : result
end

#at_xpath(*paths) ⇒ Object



26
27
28
29
# File 'lib/leptris/xml/searchable.rb', line 26

def at_xpath(*paths)
  result = xpath(*paths)
  result.is_a?(Leptris::XML::NodeSet) ? result.first : result
end

#css(*args) ⇒ Object

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
# File 'lib/leptris/xml/searchable.rb', line 43

def css(*args)
  handler, ns, _ = parse_search_args(args)
  raise ArgumentError, "namespace bindings not supported in css" if ns && !ns.empty?
  raise ArgumentError, "custom CSS handlers not supported" if handler
  expr = args.map { |r| Leptris::XML::CssToXPath.convert(r) }.join(" | ")
  xpath(expr)
end

#search(*args) ⇒ Object Also known as: /



31
32
33
34
# File 'lib/leptris/xml/searchable.rb', line 31

def search(*args)
  paths = args.first.is_a?(Array) ? args.first : [args.first]
  paths.map(&:to_s).all? { |p| looks_like_xpath?(p) } ? xpath(*paths) : css(*paths)
end

#xpath(*paths) ⇒ Object

Raises:

  • (ArgumentError)


4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/leptris/xml/searchable.rb', line 4

def xpath(*paths)
  handler, ns, _vars = parse_search_args(paths)
  raise ArgumentError, "custom XPath handlers not supported" if handler
  expr = paths.join(" | ")

  doc_ptr = is_a?(Leptris::XML::Document) ? c_ptr : document.c_ptr
  context_ptr = is_a?(Leptris::XML::Document) ? nil : c_ptr

  result_ptr =
    if ns && !ns.empty?
      xpath_eval_with_namespaces(doc_ptr, context_ptr, expr, ns)
    else
      Leptris::XML::FFI.leptris_xpath_eval(doc_ptr, context_ptr, expr)
    end
  if result_ptr.null?
    raise Leptris::XML::XPathError,
      Leptris::XML::FFI.leptris_last_error.to_s
  end

  Leptris::XML::Searchable.wrap_xpath_result(document, result_ptr)
end