Class: XmlNodeStream::Selector
- Inherits:
-
Object
- Object
- XmlNodeStream::Selector
- Defined in:
- lib/xml_node_stream/selector.rb
Overview
Partial implementation of XPath selectors. Only abbreviated paths and the text() function are supported. The rest of XPath is unecessary in the context of a Ruby application since XPath is also a programming language. If you really need an XPath function, chances are you can just do it in the Ruby code.
Example selectors:
- book - find all child book elements
- book/author - find all author elements that are children of the book child elements
- ../book - find all sibling book elements
- */author - find all author elements that are children of any child elements
- book//author - find all author elements that descendants at any level of book child elements
- .//author - find all author elements that are descendants of the current element
- /library/books/book - find all book elements with the full path /library/books/book
- author/text() - get the text values of all author child elements
Defined Under Namespace
Classes: Matcher
Constant Summary collapse
- XPATH_SEGMENT_REGEX =
/\A(\.\.?|\*|[a-zA-Z_][\w-]*|text\(\))(\|((\.\.?|\*|[a-zA-Z_][\w-]*|text\(\))))*\z/
Instance Method Summary collapse
-
#find(node) ⇒ Array<Node>
Apply the selector to the current node.
-
#initialize(path) ⇒ Selector
constructor
Create a selector.
Constructor Details
#initialize(path) ⇒ Selector
Create a selector. Path should be an abbreviated XPath string.
24 25 26 27 28 |
# File 'lib/xml_node_stream/selector.rb', line 24 def initialize(path) raise ArgumentError, "XPath pattern cannot be empty" if path.nil? || path.empty? @parts = tokenize_path(path) end |
Instance Method Details
#find(node) ⇒ Array<Node>
Apply the selector to the current node. Note, if your path started with a /, it will be applied to the root node.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/xml_node_stream/selector.rb', line 35 def find(node) matched = [node] @parts.each do |part_matchers| context = matched matched = [] part_matchers.each do |matcher| matched.concat(matcher.select(context)) end break if matched.empty? end matched end |