Class: Itonoko::XML::Node
- Inherits:
-
Object
- Object
- Itonoko::XML::Node
show all
- Defined in:
- lib/itonoko/xml/node.rb
Constant Summary
collapse
- ELEMENT_NODE =
1
- ATTRIBUTE_NODE =
2
- TEXT_NODE =
3
- CDATA_SECTION_NODE =
4
- PROCESSING_INSTRUCTION_NODE =
7
8
- DOCUMENT_NODE =
9
- DOCUMENT_TYPE_NODE =
10
- DOCUMENT_FRAGMENT_NODE =
11
- ESCAPE_TEXT =
{ "&" => "&", "<" => "<", ">" => ">" }.freeze
- ESCAPE_ATTR =
{ "&" => "&", "<" => "<", ">" => ">", '"' => """ }.freeze
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
#initialize(node_type, node_name, document = nil) ⇒ Node
Returns a new instance of Node.
22
23
24
25
26
27
28
29
|
# File 'lib/itonoko/xml/node.rb', line 22
def initialize(node_type, node_name, document = nil)
@node_type = node_type
@node_name = node_name
@document = document
@parent = nil
@children = []
@attributes = {}
end
|
Instance Attribute Details
#children ⇒ Object
Returns the value of attribute children.
20
21
22
|
# File 'lib/itonoko/xml/node.rb', line 20
def children
@children
end
|
#document ⇒ Object
Returns the value of attribute document.
19
20
21
|
# File 'lib/itonoko/xml/node.rb', line 19
def document
@document
end
|
#node_name ⇒ Object
Returns the value of attribute node_name.
20
21
22
|
# File 'lib/itonoko/xml/node.rb', line 20
def node_name
@node_name
end
|
#node_type ⇒ Object
Returns the value of attribute node_type.
20
21
22
|
# File 'lib/itonoko/xml/node.rb', line 20
def node_type
@node_type
end
|
#parent ⇒ Object
Returns the value of attribute parent.
19
20
21
|
# File 'lib/itonoko/xml/node.rb', line 19
def parent
@parent
end
|
Instance Method Details
#==(other) ⇒ Object
311
312
313
|
# File 'lib/itonoko/xml/node.rb', line 311
def ==(other)
equal?(other)
end
|
#[](attr_name) ⇒ Object
87
88
89
|
# File 'lib/itonoko/xml/node.rb', line 87
def [](attr_name)
@attributes[attr_name.to_s]
end
|
#[]=(attr_name, value) ⇒ Object
91
92
93
|
# File 'lib/itonoko/xml/node.rb', line 91
def []=(attr_name, value)
@attributes[attr_name.to_s] = value.to_s
end
|
#add_child(node_or_markup) ⇒ Object
Also known as:
<<
── tree manipulation ─────────────────────────────────────────
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/itonoko/xml/node.rb', line 148
def add_child(node_or_markup)
nodes = coerce_nodes(node_or_markup)
nodes.each do |node|
node.parent&.children&.delete(node)
node.parent = self
node.document = document
@children << node
end
nodes.length == 1 ? nodes.first : NodeSet.new(document, nodes)
end
|
#add_next_sibling(node_or_markup) ⇒ Object
Also known as:
after
171
172
173
174
175
176
177
178
179
180
181
182
|
# File 'lib/itonoko/xml/node.rb', line 171
def add_next_sibling(node_or_markup)
raise "no parent" unless parent
nodes = coerce_nodes(node_or_markup)
idx = parent.children.index(self) + 1
nodes.each_with_index do |node, i|
node.parent&.children&.delete(node)
node.parent = parent
node.document = document
parent.children.insert(idx + i, node)
end
nodes.length == 1 ? nodes.first : NodeSet.new(document, nodes)
end
|
#add_previous_sibling(node_or_markup) ⇒ Object
Also known as:
before
185
186
187
188
189
190
191
192
193
194
195
196
|
# File 'lib/itonoko/xml/node.rb', line 185
def add_previous_sibling(node_or_markup)
raise "no parent" unless parent
nodes = coerce_nodes(node_or_markup)
idx = parent.children.index(self)
nodes.each_with_index do |node, i|
node.parent&.children&.delete(node)
node.parent = parent
node.document = document
parent.children.insert(idx + i, node)
end
nodes.length == 1 ? nodes.first : NodeSet.new(document, nodes)
end
|
#ancestors(selector = nil) ⇒ Object
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/itonoko/xml/node.rb', line 62
def ancestors(selector = nil)
result = []
node = parent
while node
result << node if node.node_type != DOCUMENT_NODE
node = node.parent
end
list = NodeSet.new(document, result)
selector ? list.select { |n| n.matches_css?(selector) } : list
end
|
#at(*queries) ⇒ Object
252
253
254
|
# File 'lib/itonoko/xml/node.rb', line 252
def at(*queries)
search(*queries).first
end
|
#at_css(selector) ⇒ Object
240
241
242
|
# File 'lib/itonoko/xml/node.rb', line 240
def at_css(selector)
css(selector).first
end
|
#at_xpath(expr, namespaces = {}) ⇒ Object
244
245
246
|
# File 'lib/itonoko/xml/node.rb', line 244
def at_xpath(expr, namespaces = {})
xpath(expr, namespaces).first
end
|
#attribute(name) ⇒ Object
115
116
117
118
119
|
# File 'lib/itonoko/xml/node.rb', line 115
def attribute(name)
val = @attributes[name.to_s]
return nil unless val
Attr.new(name.to_s, val, document)
end
|
#attribute_nodes ⇒ Object
128
129
130
|
# File 'lib/itonoko/xml/node.rb', line 128
def attribute_nodes
@attributes.map { |k, v| Attr.new(k, v, document) }
end
|
#attributes ⇒ Object
121
122
123
124
125
126
|
# File 'lib/itonoko/xml/node.rb', line 121
def attributes
@attributes.transform_values { |v| Attr.new(nil, v, document) }
.tap do |h|
@attributes.each_key { |k| h[k].name = k }
end
end
|
#cdata_node? ⇒ Boolean
327
328
329
|
# File 'lib/itonoko/xml/node.rb', line 327
def cdata_node?
node_type == CDATA_SECTION_NODE
end
|
#child ⇒ Object
77
78
79
|
# File 'lib/itonoko/xml/node.rb', line 77
def child
children.first
end
|
323
324
325
|
# File 'lib/itonoko/xml/node.rb', line 323
def
node_type == COMMENT_NODE
end
|
#css(selector) ⇒ Object
── search ────────────────────────────────────────────────────
230
231
232
233
|
# File 'lib/itonoko/xml/node.rb', line 230
def css(selector)
require_relative "../css/matcher"
CSS::Matcher.match(self, selector)
end
|
#description ⇒ Object
339
340
341
|
# File 'lib/itonoko/xml/node.rb', line 339
def description
node_name
end
|
#document? ⇒ Boolean
335
336
337
|
# File 'lib/itonoko/xml/node.rb', line 335
def document?
node_type == DOCUMENT_NODE
end
|
#element? ⇒ Boolean
315
316
317
|
# File 'lib/itonoko/xml/node.rb', line 315
def element?
node_type == ELEMENT_NODE
end
|
#element_children ⇒ Object
73
74
75
|
# File 'lib/itonoko/xml/node.rb', line 73
def element_children
NodeSet.new(document, children.select { |c| c.node_type == ELEMENT_NODE })
end
|
#get_attribute(name) ⇒ Object
95
96
97
|
# File 'lib/itonoko/xml/node.rb', line 95
def get_attribute(name)
@attributes[name.to_s]
end
|
#has_attribute?(name) ⇒ Boolean
107
108
109
|
# File 'lib/itonoko/xml/node.rb', line 107
def has_attribute?(name)
@attributes.key?(name.to_s)
end
|
#inner_html ⇒ Object
── serialization ─────────────────────────────────────────────
262
263
264
|
# File 'lib/itonoko/xml/node.rb', line 262
def inner_html
children.map { |c| c.to_html }.join
end
|
#inner_html=(markup) ⇒ Object
#inspect ⇒ Object
307
308
309
|
# File 'lib/itonoko/xml/node.rb', line 307
def inspect
"#<#{self.class} name=#{node_name.inspect} children=#{children.length}>"
end
|
#keys ⇒ Object
111
112
113
|
# File 'lib/itonoko/xml/node.rb', line 111
def keys
@attributes.keys
end
|
#matches?(selector) ⇒ Boolean
#name ⇒ Object
── attributes ────────────────────────────────────────────────
83
84
85
|
# File 'lib/itonoko/xml/node.rb', line 83
def name
node_name
end
|
#next_element ⇒ Object
50
51
52
53
54
|
# File 'lib/itonoko/xml/node.rb', line 50
def next_element
sib = next_sibling
sib = sib.next_sibling while sib && sib.node_type != ELEMENT_NODE
sib
end
|
#next_sibling ⇒ Object
38
39
40
41
42
|
# File 'lib/itonoko/xml/node.rb', line 38
def next_sibling
return nil unless parent
idx = parent.children.index(self)
idx && parent.children[idx + 1]
end
|
#prepend_child(node_or_markup) ⇒ Object
160
161
162
163
164
165
166
167
168
169
|
# File 'lib/itonoko/xml/node.rb', line 160
def prepend_child(node_or_markup)
nodes = coerce_nodes(node_or_markup)
nodes.reverse_each do |node|
node.parent&.children&.delete(node)
node.parent = self
node.document = document
@children.unshift(node)
end
nodes.length == 1 ? nodes.first : NodeSet.new(document, nodes)
end
|
#previous_element ⇒ Object
56
57
58
59
60
|
# File 'lib/itonoko/xml/node.rb', line 56
def previous_element
sib = previous_sibling
sib = sib.previous_sibling while sib && sib.node_type != ELEMENT_NODE
sib
end
|
#previous_sibling ⇒ Object
44
45
46
47
48
|
# File 'lib/itonoko/xml/node.rb', line 44
def previous_sibling
return nil unless parent
idx = parent.children.index(self)
idx && idx > 0 ? parent.children[idx - 1] : nil
end
|
#remove ⇒ Object
Also known as:
unlink
199
200
201
202
203
|
# File 'lib/itonoko/xml/node.rb', line 199
def remove
parent&.children&.delete(self)
@parent = nil
self
end
|
#remove_attribute(name) ⇒ Object
103
104
105
|
# File 'lib/itonoko/xml/node.rb', line 103
def remove_attribute(name)
@attributes.delete(name.to_s)
end
|
#replace(node_or_markup) ⇒ Object
206
207
208
209
210
211
212
213
214
215
216
217
218
|
# File 'lib/itonoko/xml/node.rb', line 206
def replace(node_or_markup)
raise "no parent" unless parent
nodes = coerce_nodes(node_or_markup)
idx = parent.children.index(self)
parent.children.delete_at(idx)
nodes.reverse_each do |node|
node.parent = parent
node.document = document
parent.children.insert(idx, node)
end
@parent = nil
nodes.length == 1 ? nodes.first : NodeSet.new(document, nodes)
end
|
#root ⇒ Object
── navigation ────────────────────────────────────────────────
33
34
35
36
|
# File 'lib/itonoko/xml/node.rb', line 33
def root
return self if parent.nil? || parent.node_type == DOCUMENT_NODE
parent.root
end
|
#search(*queries) ⇒ Object
248
249
250
|
# File 'lib/itonoko/xml/node.rb', line 248
def search(*queries)
NodeSet.new(document, queries.flat_map { |q| css(q).to_a })
end
|
#set_attribute(name, value) ⇒ Object
99
100
101
|
# File 'lib/itonoko/xml/node.rb', line 99
def set_attribute(name, value)
@attributes[name.to_s] = value.to_s
end
|
#text ⇒ Object
Also known as:
content, inner_text
── content ───────────────────────────────────────────────────
134
135
136
|
# File 'lib/itonoko/xml/node.rb', line 134
def text
children.map(&:text).join
end
|
#text=(str) ⇒ Object
Also known as:
content=
140
141
142
143
|
# File 'lib/itonoko/xml/node.rb', line 140
def text=(str)
@children = [Text.new(str.to_s, document)]
@children.first.parent = self
end
|
#text? ⇒ Boolean
319
320
321
|
# File 'lib/itonoko/xml/node.rb', line 319
def text?
node_type == TEXT_NODE
end
|
#to_s ⇒ Object
303
304
305
|
# File 'lib/itonoko/xml/node.rb', line 303
def to_s
to_html
end
|
#to_xml(options = {}) ⇒ Object
#xpath(expr, namespaces = {}) ⇒ Object
235
236
237
238
|
# File 'lib/itonoko/xml/node.rb', line 235
def xpath(expr, namespaces = {})
require_relative "../xpath/evaluator"
XPath::Evaluator.new(self, namespaces).evaluate(expr)
end
|