Class: Nokolexbor::Node
- Inherits:
-
Object
- Object
- Nokolexbor::Node
- Includes:
- Enumerable
- Defined in:
- lib/nokolexbor/node.rb,
ext/nokolexbor/nl_node.c
Direct Known Subclasses
Attribute, CharacterData, Document, DocumentFragment, Element, NodeSet, ProcessingInstruction
Constant Summary collapse
- ELEMENT_NODE =
1
- ATTRIBUTE_NODE =
2
- TEXT_NODE =
3
- CDATA_SECTION_NODE =
4
- ENTITY_REF_NODE =
5
- ENTITY_NODE =
6
- PI_NODE =
7
- COMMENT_NODE =
8
- DOCUMENT_NODE =
9
- DOCUMENT_TYPE_NODE =
10
- DOCUMENT_FRAG_NODE =
11
- NOTATION_NODE =
12
- LOOKS_LIKE_XPATH =
%r{^(\./|/|\.\.|\.$)}
Instance Attribute Summary collapse
-
#document ⇒ Document
readonly
The associated Document of this node.
Class Method Summary collapse
-
.new(name, document) {|Node| ... } ⇒ Node
Create a new node with
name
that belongs todocument
.
Instance Method Summary collapse
-
#<<(node_or_tags) ⇒ Node
Add
node_or_tags
as a child of this Node. -
#==(other) ⇒ Boolean
True if this Node is equal to
other
. -
#[](name) ⇒ String?
(also: #attr, #get_attribute)
Fetch an attribute from this node.
-
#[]=(name, value) ⇒ String?
(also: #set_attr, #set_attribute)
Update the attribute
name
tovalue
, or create the attribute if it does not exist. -
#add_child(new) ⇒ Node, NodeSet
Add
new
as a child of this Node. -
#add_class(names) ⇒ Node
Ensure CSS classes are present on
self
. -
#add_next_sibling(node_or_tags) ⇒ Node, NodeSet
(also: #next=)
Insert
node_or_tags
after this Node (as a sibling). -
#add_previous_sibling(node_or_tags) ⇒ Node, NodeSet
(also: #previous=)
Insert
node_or_tags
before this Node (as a sibling). -
#add_sibling(next_or_previous, new) ⇒ Node, NodeSet
Insert
node_or_tags
before or after this Node (as a sibling). -
#after(node_or_tags) ⇒ Node
Insert
node_or_tags
after this Node (as a sibling). -
#ancestors(selector = nil) ⇒ NodeSet
Get a list of ancestor Node of this Node.
-
#append_class(names) ⇒ Node
Add CSS classes to
self
, regardless of duplication. -
#at(*args) ⇒ Node?
(also: #%)
Like #search, but returns the first match.
-
#at_css(*args) ⇒ Node?
Like #css, but returns the first match.
-
#at_css_impl(selector) ⇒ Object
Internal implementation of #at_css.
-
#at_xpath(*args) ⇒ Node?
Like #xpath, but returns the first match.
-
#attribute(name) ⇒ Attribute
The attribute belonging to this node with name
name
. -
#attribute_nodes ⇒ Array<Attribute>
An array of Attribute belonging to this node.
-
#attributes ⇒ Hash{String => Attribute}
Fetch this node’s attributes.
-
#attrs ⇒ Hash{String => String}
Get a hash of attribute names and values of this Node.
-
#before(node_or_tags) ⇒ Node
Insert
node_or_tags
before this Node (as a sibling). -
#cdata? ⇒ Boolean
True if this is a CDATA.
-
#child ⇒ Node?
Get the first child of this node.
-
#children ⇒ NodeSet
Get the children of this node.
-
#children=(node) ⇒ Object
(also: #inner_html=)
Set the content of this Node.
-
#classes ⇒ Array
Fetch CSS class names of a Node.
-
#clone ⇒ Node
(also: #dup)
Copy this node.
-
#comment? ⇒ Boolean
True if this is a Comment.
-
#content ⇒ String
(also: #text, #inner_text, #to_str)
Contents of all the text nodes in this node’s subtree, concatenated together into a single String.
-
#content=(content) ⇒ String
Set the Node’s content to a Text node containing
content
. -
#css(*args) ⇒ NodeSet
Search this object for CSS
rules
. -
#css_impl(selector) ⇒ Object
Internal implementation of #css.
-
#css_path ⇒ Object
Get the path to this node as a CSS expression.
-
#destroy ⇒ nil
Remove this node from its current context and free its allocated memory.
-
#document? ⇒ Boolean
True if this is a Document.
-
#each {|String, String| ... } ⇒ Object
Iterate over each attribute name and value pair of this Node.
-
#element? ⇒ Boolean
(also: #elem?)
True if this is an Element.
-
#element_children ⇒ NodeSet
(also: #elements)
Get the element children of this node.
-
#first_element_child ⇒ Element
The first child Node that is an element.
-
#fragment(tags) ⇒ DocumentFragment
Create a DocumentFragment containing
tags
that is relative to this context node. -
#fragment? ⇒ Boolean
True if this is a DocumentFragment.
-
#inner_html(*args) ⇒ String
Get the inner_html of this Node.
- #inspect(*args) ⇒ Object
-
#key?(name) ⇒ Boolean
(also: #has_attribute?)
True if
name
is set. -
#keys ⇒ Array<String>
Get the attribute names of this Node.
-
#kwattr_add(attribute_name, keywords) ⇒ Node
Ensure that values are present in a keyword attribute.
-
#kwattr_append(attribute_name, keywords) ⇒ Node
Add keywords to a Node’s keyword attribute, regardless of duplication.
-
#kwattr_remove(attribute_name, keywords) ⇒ Node
Remove keywords from a keyword attribute.
-
#kwattr_values(attribute_name) ⇒ Array<String>
Fetch values from a keyword attribute of a Node.
-
#last_element_child ⇒ Element
The last child Node that is an element.
-
#matches?(selector) ⇒ Boolean
True if this Node matches
selector
. -
#name ⇒ String
(also: #node_name)
Get the name of this Node.
-
#next ⇒ Node?
(also: #next_sibling)
Get the next sibling node.
-
#next_element ⇒ Element?
Get the next sibling element.
-
#node_type ⇒ Integer
(also: #type)
Get the type of this Node.
-
#nokogiri_at_css(*args) ⇒ Node?
Like #nokogiri_css, but returns the first match.
-
#nokogiri_css(*args) ⇒ NodeSet
Search this object for CSS
rules
. -
#outer_html(*args) ⇒ String
(also: #to_html, #serialize, #to_s)
Serialize this Node to HTML, also known as outer_html.
-
#parent ⇒ Node?
Get the parent node.
-
#parent=(parent_node) ⇒ Object
Set the parent Node of this Node.
-
#parse(html) ⇒ NodeSet
Parse
html
as a document fragment within the context of this node. -
#path ⇒ String
The path associated with this Node.
-
#prepend_child(node) ⇒ Node, NodeSet
Add
node
as the first child of this Node. -
#previous ⇒ Node?
(also: #previous_sibling)
Get the previous sibling node.
-
#previous_element ⇒ Element?
Get the previous sibling element.
-
#processing_instruction? ⇒ Boolean
True if this is a ProcessingInstruction.
-
#remove ⇒ Node
(also: #unlink)
Remove this node from its current context.
-
#remove_attr(name) ⇒ Boolean
(also: #delete, #remove_attribute)
Remove the attribute named
name
. -
#remove_class(names = nil) ⇒ Node
Remove CSS classes from this node.
-
#replace(node) ⇒ Node, NodeSet
Replace this Node with
node
. -
#search(*args) ⇒ NodeSet
(also: #/)
Search this object for
paths
. -
#source_location ⇒ Integer
The node’s location at the source HTML.
-
#swap(node) ⇒ Node
Swap this Node for
node
. -
#text? ⇒ Boolean
True if this is a Text.
-
#traverse { ... } ⇒ Object
Traverse self and all children.
-
#value?(value) ⇒ Boolean
True if this Node’s attributes include <value>.
-
#values ⇒ Array<String>
Get the attribute values of this Node.
-
#wrap(node) ⇒ Node
Wrap this Node with another node.
-
#write_to(io, *options) ⇒ Object
(also: #write_html_to)
Serialize Node and write to
io
. -
#xpath(*args) ⇒ NodeSet
Search this node for XPath
paths
.
Instance Attribute Details
Class Method Details
.new(name, document) {|Node| ... } ⇒ Node
Create a new node with name
that belongs to document
.
If you intend to add a node to a document tree, it’s likely that you will prefer one of the Nokolexbor::Node methods like #add_child, #add_next_sibling, #replace, etc. which will both create an element (or subtree) and place it in the document tree.
Another alternative, if you are concerned about performance, is Document#create_element which accepts additional arguments for contents or attributes but (like this method) avoids parsing markup.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'ext/nokolexbor/nl_node.c', line 106
static VALUE
nl_node_new(int argc, VALUE *argv, VALUE klass)
{
lxb_dom_document_t *document;
VALUE rb_name;
VALUE rb_document;
VALUE rest;
rb_scan_args(argc, argv, "2*", &rb_name, &rb_document, &rest);
if (!rb_obj_is_kind_of(rb_document, cNokolexborDocument)) {
rb_raise(rb_eArgError, "Document must be a Nokolexbor::Document");
}
document = nl_rb_document_unwrap(rb_document);
const char *c_name = StringValuePtr(rb_name);
size_t name_len = RSTRING_LEN(rb_name);
lxb_dom_element_t *element = lxb_dom_document_create_element(document, (const lxb_char_t *)c_name, name_len, NULL);
if (element == NULL) {
rb_raise(rb_eRuntimeError, "Error creating element");
}
VALUE rb_node = nl_rb_node_create(&element->node, rb_document);
if (rb_block_given_p()) {
rb_yield(rb_node);
}
return rb_node;
}
|
Instance Method Details
#<<(node_or_tags) ⇒ Node
Add node_or_tags
as a child of this Node.
208 209 210 211 |
# File 'lib/nokolexbor/node.rb', line 208 def <<() add_child() self end |
#==(other) ⇒ Boolean
Returns true if this Node is equal to other
.
872 873 874 875 876 877 878 879 880 881 |
# File 'ext/nokolexbor/nl_node.c', line 872
static VALUE
nl_node_equals(VALUE self, VALUE other)
{
if (!rb_obj_is_kind_of(other, cNokolexborNode)) {
return Qfalse;
}
lxb_dom_node_t *node1 = nl_rb_node_unwrap(self);
lxb_dom_node_t *node2 = nl_rb_node_unwrap(other);
return node1 == node2 ? Qtrue : Qfalse;
}
|
#[](name) ⇒ String? Also known as: attr, get_attribute
Fetch an attribute from this node.
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'ext/nokolexbor/nl_node.c', line 245
static VALUE
nl_node_get_attr(VALUE self, VALUE rb_attr)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return Qnil;
}
VALUE rb_attr_s = rb_String(rb_attr);
const char *attr_c = RSTRING_PTR(rb_attr_s);
size_t attr_len = RSTRING_LEN(rb_attr_s);
lxb_dom_element_t *element = lxb_dom_interface_element(node);
if (!lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len)) {
return Qnil;
}
size_t attr_value_len;
const lxb_char_t *attr_value = lxb_dom_element_get_attribute(element, (const lxb_char_t *)attr_c, attr_len, &attr_value_len);
return rb_utf8_str_new((const char *)attr_value, attr_value_len);
}
|
#[]=(name, value) ⇒ String? Also known as: set_attr, set_attribute
Update the attribute name
to value
, or create the attribute if it does not exist.
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'ext/nokolexbor/nl_node.c', line 280
static VALUE
nl_node_set_attr(VALUE self, VALUE rb_attr, VALUE rb_value)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return Qnil;
}
VALUE rb_attr_s = rb_String(rb_attr);
VALUE rb_value_s = rb_String(rb_value);
const char *attr_c = RSTRING_PTR(rb_attr_s);
size_t attr_len = RSTRING_LEN(rb_attr_s);
const char *value_c = RSTRING_PTR(rb_value_s);
size_t value_len = RSTRING_LEN(rb_value_s);
lxb_dom_element_t *element = lxb_dom_interface_element(node);
lxb_dom_element_set_attribute(element, (const lxb_char_t *)attr_c, attr_len, (const lxb_char_t *)value_c, value_len);
return rb_value;
}
|
#add_child(new) ⇒ Node, NodeSet
Add new
as a child of this Node.
1036 1037 1038 1039 1040 |
# File 'ext/nokolexbor/nl_node.c', line 1036
static VALUE
nl_node_add_child(VALUE self, VALUE new)
{
return nl_node_add_nodes(self, new, lxb_dom_node_insert_child, false);
}
|
#add_class(names) ⇒ Node
Ensure CSS classes are present on self
. Any CSS classes in names
that already exist in the “class” attribute are not added. Note that any existing duplicates in the “class” attribute are not removed. Compare with #append_class.
This is a convenience function and is equivalent to:
node.kwattr_add("class", names)
481 482 483 |
# File 'lib/nokolexbor/node.rb', line 481 def add_class(names) kwattr_add("class", names) end |
#add_next_sibling(node_or_tags) ⇒ Node, NodeSet Also known as: next=
Insert node_or_tags
after this Node (as a sibling).
165 166 167 168 169 170 |
# File 'lib/nokolexbor/node.rb', line 165 def add_next_sibling() raise ArgumentError, "A document may not have multiple root nodes." if parent&.document? && !(.comment? || .processing_instruction?) add_sibling(:next, ) end |
#add_previous_sibling(node_or_tags) ⇒ Node, NodeSet Also known as: previous=
Insert node_or_tags
before this Node (as a sibling).
151 152 153 154 155 156 |
# File 'lib/nokolexbor/node.rb', line 151 def add_previous_sibling() raise ArgumentError, "A document may not have multiple root nodes." if parent&.document? && !(.comment? || .processing_instruction?) add_sibling(:previous, ) end |
#add_sibling(next_or_previous, new) ⇒ Node, NodeSet
Insert node_or_tags
before or after this Node (as a sibling).
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 |
# File 'ext/nokolexbor/nl_node.c', line 1013
static VALUE
nl_node_add_sibling(VALUE self, VALUE next_or_previous, VALUE new)
{
bool insert_after;
if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("next"))) {
insert_after = true;
} else if (rb_eql(rb_String(next_or_previous), rb_str_new_literal("previous"))) {
insert_after = false;
} else {
rb_raise(rb_eArgError, "Unsupported inserting position");
}
return insert_after ? nl_node_add_nodes(self, new, lxb_dom_node_insert_after, true)
: nl_node_add_nodes(self, new, lxb_dom_node_insert_before, false);
}
|
#after(node_or_tags) ⇒ Node
Insert node_or_tags
after this Node (as a sibling).
191 192 193 194 |
# File 'lib/nokolexbor/node.rb', line 191 def after() add_next_sibling() self end |
#ancestors(selector = nil) ⇒ NodeSet
Get a list of ancestor Node of this Node
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/nokolexbor/node.rb', line 73 def ancestors(selector = nil) return NodeSet.new(@document) unless respond_to?(:parent) return NodeSet.new(@document) unless parent parents = [parent] while parents.last.respond_to?(:parent) break unless (ctx_parent = parents.last.parent) parents << ctx_parent end return NodeSet.new(@document, parents) unless selector root = parents.last search_results = root.search(selector) NodeSet.new(@document, parents.find_all do |parent| search_results.include?(parent) end) end |
#append_class(names) ⇒ Node
Add CSS classes to self
, regardless of duplication. Compare with #add_class.
This is a convenience function and is equivalent to:
node.kwattr_append("class", names)
497 498 499 |
# File 'lib/nokolexbor/node.rb', line 497 def append_class(names) kwattr_append("class", names) end |
#at(*args) ⇒ Node? Also known as: %
Like #search, but returns the first match.
422 423 424 425 426 427 428 429 430 |
# File 'lib/nokolexbor/node.rb', line 422 def at(*args) paths, handler, ns, binds = extract_params(args) if paths.size == 1 && !LOOKS_LIKE_XPATH.match?(paths.first) return at_css(paths.first) end at_xpath(*(paths + [ns, handler, binds].compact)) end |
#at_css(*args) ⇒ Node?
Like #css, but returns the first match.
This method uses Lexbor as the selector engine. Its performance is much higher than #at_xpath or #nokogiri_at_css.
346 347 348 |
# File 'lib/nokolexbor/node.rb', line 346 def at_css(*args) at_css_impl(args.join(', ')) end |
#at_css_impl(selector) ⇒ Object
Internal implementation of #at_css
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
# File 'ext/nokolexbor/nl_node.c', line 465
static VALUE
nl_node_at_css(VALUE self, VALUE selector)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lexbor_array_t *array = lexbor_array_create();
lxb_status_t status = nl_node_find(self, selector, nl_node_at_css_callback, array);
if (status != LXB_STATUS_OK) {
lexbor_array_destroy(array, true);
nl_raise_lexbor_error(status);
}
if (array->length == 0) {
lexbor_array_destroy(array, true);
return Qnil;
}
nl_sort_nodes_if_necessary(selector, node->owner_document, array);
VALUE ret = nl_rb_node_create(array->list[0], nl_rb_document_get(self));
lexbor_array_destroy(array, true);
return ret;
}
|
#at_xpath(*args) ⇒ Node?
Like #xpath, but returns the first match.
It works the same way as Nokogiri::Node#at_xpath.
398 399 400 |
# File 'lib/nokolexbor/node.rb', line 398 def at_xpath(*args) xpath(*args).first end |
#attribute(name) ⇒ Attribute
Returns The attribute belonging to this node with name name
.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'ext/nokolexbor/nl_node.c', line 143
static VALUE
nl_node_attribute(VALUE self, VALUE rb_name)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
const char *c_name = StringValuePtr(rb_name);
size_t name_len = RSTRING_LEN(rb_name);
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return Qnil;
}
lxb_dom_attr_t *attr = lxb_dom_element_attr_by_name(lxb_dom_interface_element(node), (const lxb_char_t *)c_name, name_len);
if (attr == NULL) {
return Qnil;
}
if (attr->owner == NULL) {
attr->owner = lxb_dom_interface_element(node);
}
return nl_rb_node_create(attr, nl_rb_document_get(self));
}
|
#attribute_nodes ⇒ Array<Attribute>
Returns An array of Attribute belonging to this node.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'ext/nokolexbor/nl_node.c', line 168
static VALUE
nl_node_attribute_nodes(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
VALUE ary = rb_ary_new();
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return ary;
}
lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
if (attr == NULL) {
return ary;
}
VALUE rb_doc = nl_rb_document_get(self);
while (attr != NULL) {
if (attr->owner == NULL) {
attr->owner = lxb_dom_interface_element(node);
}
rb_ary_push(ary, nl_rb_node_create(attr, rb_doc));
attr = attr->next;
}
return ary;
}
|
#attributes ⇒ Hash{String => Attribute}
Fetch this node’s attributes.
248 249 250 251 252 |
# File 'lib/nokolexbor/node.rb', line 248 def attributes attribute_nodes.each_with_object({}) do |node, hash| hash[node.name] = node end end |
#attrs ⇒ Hash{String => String}
Get a hash of attribute names and values of this Node.
686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 |
# File 'ext/nokolexbor/nl_node.c', line 686
static VALUE
nl_node_attrs(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
VALUE rb_hash = rb_hash_new();
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return rb_hash;
}
lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
while (attr != NULL) {
size_t tmp_len;
const lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
VALUE rb_key = rb_utf8_str_new((const char *)tmp, tmp_len);
tmp = lxb_dom_attr_value(attr, &tmp_len);
VALUE rb_value = tmp != NULL ? rb_utf8_str_new((const char *)tmp, tmp_len) : rb_str_new("", 0);
rb_hash_aset(rb_hash, rb_key, rb_value);
attr = lxb_dom_element_next_attribute(attr);
}
return rb_hash;
}
|
#before(node_or_tags) ⇒ Node
Insert node_or_tags
before this Node (as a sibling).
179 180 181 182 |
# File 'lib/nokolexbor/node.rb', line 179 def before() add_previous_sibling() self end |
#cdata? ⇒ Boolean
Returns true if this is a CDATA.
31 32 33 |
# File 'lib/nokolexbor/node.rb', line 31 def cdata? type == CDATA_SECTION_NODE end |
#child ⇒ Node?
Get the first child of this node.
833 834 835 836 837 838 839 |
# File 'ext/nokolexbor/nl_node.c', line 833
static VALUE
nl_node_child(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_t *child = node->first_child;
return child ? nl_rb_node_create(child, nl_rb_document_get(self)) : Qnil;
}
|
#children ⇒ NodeSet
Get the children of this node.
791 792 793 794 795 796 797 798 799 800 801 802 803 804 |
# File 'ext/nokolexbor/nl_node.c', line 791
static VALUE
nl_node_children(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_t *child = node->first_child;
lexbor_array_t *array = lexbor_array_create();
while (child != NULL) {
lexbor_array_push(array, child);
child = child->next;
}
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
}
|
#children=(node) ⇒ Object Also known as: inner_html=
Set the content of this Node.
284 285 286 287 |
# File 'lib/nokolexbor/node.rb', line 284 def children=(node) children.remove add_child(node) end |
#classes ⇒ Array
Fetch CSS class names of a Node.
This is a convenience function and is equivalent to:
node.kwattr_values("class")
451 452 453 |
# File 'lib/nokolexbor/node.rb', line 451 def classes kwattr_values("class") end |
#clone ⇒ Node Also known as: dup
Copy this node.
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 |
# File 'ext/nokolexbor/nl_node.c', line 1094
static VALUE
nl_node_clone(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_t *clone;
switch (node->type) {
case LXB_DOM_NODE_TYPE_ATTRIBUTE:
clone = (lxb_dom_node_t *)lxb_dom_attr_interface_clone(node->owner_document, lxb_dom_interface_attr(node));
case LXB_DOM_NODE_TYPE_CDATA_SECTION:
clone = (lxb_dom_node_t *)lxb_dom_cdata_section_interface_clone(node->owner_document, lxb_dom_interface_cdata_section(node));
default:
clone = lxb_dom_node_clone(node, true);
break;
}
return nl_rb_node_create(clone, nl_rb_document_get(self));
}
|
#comment? ⇒ Boolean
Returns true if this is a Comment.
26 27 28 |
# File 'lib/nokolexbor/node.rb', line 26 def comment? type == COMMENT_NODE end |
#content ⇒ String Also known as: text, inner_text, to_str
Returns Contents of all the text nodes in this node’s subtree, concatenated together into a single String.
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'ext/nokolexbor/nl_node.c', line 200
static VALUE
nl_node_content(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
size_t str_len = 0;
lxb_char_t *text = lxb_dom_node_text_content(node, &str_len);
if (text == NULL) {
return rb_str_new("", 0);
}
VALUE rb_str = rb_utf8_str_new((char *)text, str_len);
lxb_dom_document_destroy_text(node->owner_document, text);
return rb_str;
}
|
#content=(content) ⇒ String
Set the Node’s content to a Text node containing content
. The string gets XML escaped, not interpreted as markup.
222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'ext/nokolexbor/nl_node.c', line 222
static VALUE
nl_node_content_set(VALUE self, VALUE content)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
const char *c_content = StringValuePtr(content);
size_t content_len = RSTRING_LEN(content);
lxb_status_t status = lxb_dom_node_text_content_set(node, (const lxb_char_t *)c_content, content_len);
if (status != LXB_STATUS_OK) {
nl_raise_lexbor_error(status);
}
return content;
}
|
#css(*args) ⇒ NodeSet
Search this object for CSS rules
. rules
must be one or more CSS selectors.
This method uses Lexbor as the selector engine. Its performance is much higher than #xpath or #nokogiri_css.
334 335 336 |
# File 'lib/nokolexbor/node.rb', line 334 def css(*args) css_impl(args.join(', ')) end |
#css_impl(selector) ⇒ Object
Internal implementation of #css
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'ext/nokolexbor/nl_node.c', line 497
static VALUE
nl_node_css(VALUE self, VALUE selector)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lexbor_array_t *array = lexbor_array_create();
lxb_status_t status = nl_node_find(self, selector, nl_node_css_callback, array);
if (status != LXB_STATUS_OK) {
lexbor_array_destroy(array, true);
nl_raise_lexbor_error(status);
}
nl_sort_nodes_if_necessary(selector, node->owner_document, array);
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
}
|
#css_path ⇒ Object
Get the path to this node as a CSS expression
62 63 64 65 66 |
# File 'lib/nokolexbor/node.rb', line 62 def css_path path.split(%r{/}).filter_map do |part| part.empty? ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)') end.join(" > ") end |
#destroy ⇒ nil
Remove this node from its current context and free its allocated memory.
861 862 863 864 865 866 867 |
# File 'ext/nokolexbor/nl_node.c', line 861
static VALUE
nl_node_destroy(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_destroy(node);
return Qnil;
}
|
#document? ⇒ Boolean
Returns true if this is a Document.
57 58 59 |
# File 'lib/nokolexbor/node.rb', line 57 def document? is_a?(Nokolexbor::Document) end |
#each {|String, String| ... } ⇒ Object
Iterate over each attribute name and value pair of this Node.
304 305 306 307 308 |
# File 'lib/nokolexbor/node.rb', line 304 def each attributes.each do |name, node| yield [name, node.value] end end |
#element? ⇒ Boolean Also known as: elem?
Returns true if this is an Element.
51 52 53 |
# File 'lib/nokolexbor/node.rb', line 51 def element? type == ELEMENT_NODE end |
#element_children ⇒ NodeSet Also known as: elements
Get the element children of this node.
811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
# File 'ext/nokolexbor/nl_node.c', line 811
static VALUE
nl_node_element_children(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_t *child = node->first_child;
lexbor_array_t *array = lexbor_array_create();
while (child != NULL) {
if (child->type == LXB_DOM_NODE_TYPE_ELEMENT) {
lexbor_array_push(array, child);
}
child = child->next;
}
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
}
|
#first_element_child ⇒ Element
Returns The first child Node that is an element.
1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 |
# File 'ext/nokolexbor/nl_node.c', line 1056
static VALUE
nl_node_first_element_child(VALUE self)
{
lxb_dom_node_t *parent = nl_rb_node_unwrap(self);
lxb_dom_node_t *cur = parent->first_child;
while (cur != NULL) {
if (cur->type == LXB_DOM_NODE_TYPE_ELEMENT) {
return nl_rb_node_create(cur, nl_rb_document_get(self));
}
cur = cur->next;
}
return Qnil;
}
|
#fragment(tags) ⇒ DocumentFragment
Create a DocumentFragment containing tags
that is relative to this context node.
314 315 316 |
# File 'lib/nokolexbor/node.rb', line 314 def fragment() Nokolexbor::DocumentFragment.new(document, , self) end |
#fragment? ⇒ Boolean
Returns true if this is a DocumentFragment.
46 47 48 |
# File 'lib/nokolexbor/node.rb', line 46 def fragment? type == DOCUMENT_FRAG_NODE end |
#inner_html(*args) ⇒ String
Get the inner_html of this Node.
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
# File 'ext/nokolexbor/nl_node.c', line 519
static VALUE
nl_node_inner_html(int argc, VALUE *argv, VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lexbor_str_t str = {0};
VALUE options;
lxb_status_t status;
size_t indent = 0;
rb_scan_args(argc, argv, "01", &options);
if (TYPE(options) == T_HASH) {
VALUE rb_indent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
if (!NIL_P(rb_indent)) {
indent = NUM2INT(rb_indent);
}
}
if (indent > 0) {
status = lxb_html_serialize_pretty_deep_str(node, 0, 0, &str);
} else {
status = lxb_html_serialize_deep_str(node, &str);
}
if (status != LXB_STATUS_OK) {
if (str.data != NULL) {
lexbor_str_destroy(&str, node->owner_document->text, false);
}
nl_raise_lexbor_error(status);
}
if (str.data != NULL) {
VALUE ret = rb_utf8_str_new((const char *)str.data, str.length);
lexbor_str_destroy(&str, node->owner_document->text, false);
return ret;
}
return Qnil;
}
|
#inspect(*args) ⇒ Object
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 |
# File 'ext/nokolexbor/nl_node.c', line 1112
static VALUE
nl_node_inspect(int argc, VALUE *argv, VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
if (node->type == LXB_DOM_NODE_TYPE_DOCUMENT) {
return rb_call_super(argc, argv);
}
VALUE c = rb_class_name(CLASS_OF(self));
lexbor_str_t str = {0};
lxb_status_t status = lxb_html_serialize_str(node, &str);
if (status != LXB_STATUS_OK) {
if (str.data != NULL) {
lexbor_str_destroy(&str, node->owner_document->text, false);
}
return rb_call_super(argc, argv);
}
if (str.data != NULL) {
VALUE ret = rb_sprintf("#<%" PRIsVALUE " %s>", c, str.data);
lexbor_str_destroy(&str, node->owner_document->text, false);
return ret;
}
return rb_call_super(argc, argv);
}
|
#key?(name) ⇒ Boolean Also known as: has_attribute?
Returns true if name
is set.
603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
# File 'ext/nokolexbor/nl_node.c', line 603
static VALUE
nl_node_has_key(VALUE self, VALUE rb_attr)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return Qfalse;
}
VALUE rb_attr_s = rb_String(rb_attr);
const char *attr_c = RSTRING_PTR(rb_attr_s);
size_t attr_len = RSTRING_LEN(rb_attr_s);
lxb_dom_element_t *element = lxb_dom_interface_element(node);
return lxb_dom_element_has_attribute(element, (const lxb_char_t *)attr_c, attr_len) ? Qtrue : Qfalse;
}
|
#keys ⇒ Array<String>
Get the attribute names of this Node.
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 |
# File 'ext/nokolexbor/nl_node.c', line 626
static VALUE
nl_node_keys(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
VALUE ary_keys = rb_ary_new();
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return ary_keys;
}
lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
while (attr != NULL) {
size_t tmp_len;
const lxb_char_t *tmp = lxb_dom_attr_qualified_name(attr, &tmp_len);
rb_ary_push(ary_keys, rb_utf8_str_new((const char *)tmp, tmp_len));
attr = lxb_dom_element_next_attribute(attr);
}
return ary_keys;
}
|
#kwattr_add(attribute_name, keywords) ⇒ Node
Ensure that values are present in a keyword attribute.
Any values in keywords
that already exist in the Node’s attribute values are not added. Note that any existing duplicates in the attribute values are not removed. Compare with #kwattr_append.
A “keyword attribute” is a node attribute that contains a set of space-delimited values. Perhaps the most familiar example of this is the HTML “class” attribute used to contain CSS classes. But other keyword attributes exist, for instance the “rel” attribute.
576 577 578 579 580 581 582 |
# File 'lib/nokolexbor/node.rb', line 576 def kwattr_add(attribute_name, keywords) keywords = keywordify(keywords) current_kws = kwattr_values(attribute_name) new_kws = (current_kws + (keywords - current_kws)).join(" ") set_attr(attribute_name, new_kws) self end |
#kwattr_append(attribute_name, keywords) ⇒ Node
Add keywords to a Node’s keyword attribute, regardless of duplication. Compare with #kwattr_add.
A “keyword attribute” is a node attribute that contains a set of space-delimited values. Perhaps the most familiar example of this is the HTML “class” attribute used to contain CSS classes. But other keyword attributes exist, for instance the “rel” attribute.
605 606 607 608 609 610 611 |
# File 'lib/nokolexbor/node.rb', line 605 def kwattr_append(attribute_name, keywords) keywords = keywordify(keywords) current_kws = kwattr_values(attribute_name) new_kws = (current_kws + keywords).join(" ") set_attr(attribute_name, new_kws) self end |
#kwattr_remove(attribute_name, keywords) ⇒ Node
Remove keywords from a keyword attribute. Any matching keywords that exist in the named attribute are removed, including any multiple entries.
If no keywords remain after this operation, or if keywords
is nil
, the attribute is deleted from the node.
A “keyword attribute” is a node attribute that contains a set of space-delimited values. Perhaps the most familiar example of this is the HTML “class” attribute used to contain CSS classes. But other keyword attributes exist, for instance the “rel” attribute.
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
# File 'lib/nokolexbor/node.rb', line 637 def kwattr_remove(attribute_name, keywords) if keywords.nil? remove_attr(attribute_name) return self end keywords = keywordify(keywords) current_kws = kwattr_values(attribute_name) new_kws = current_kws - keywords if new_kws.empty? remove_attr(attribute_name) else set_attr(attribute_name, new_kws.join(" ")) end self end |
#kwattr_values(attribute_name) ⇒ Array<String>
Fetch values from a keyword attribute of a Node.
A “keyword attribute” is a node attribute that contains a set of space-delimited values. Perhaps the most familiar example of this is the HTML “class” attribute used to contain CSS classes. But other keyword attributes exist, for instance the “rel” attribute.
@#kwattr_append @#kwattr_remove
548 549 550 |
# File 'lib/nokolexbor/node.rb', line 548 def kwattr_values(attribute_name) keywordify(attr(attribute_name) || []) end |
#last_element_child ⇒ Element
Returns The last child Node that is an element.
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
# File 'ext/nokolexbor/nl_node.c', line 1074
static VALUE
nl_node_last_element_child(VALUE self)
{
lxb_dom_node_t *parent = nl_rb_node_unwrap(self);
lxb_dom_node_t *cur = parent->last_child;
while (cur != NULL) {
if (cur->type == LXB_DOM_NODE_TYPE_ELEMENT) {
return nl_rb_node_create(cur, nl_rb_document_get(self));
}
cur = cur->prev;
}
return Qnil;
}
|
#matches?(selector) ⇒ Boolean
Returns true if this Node matches selector
.
241 242 243 |
# File 'lib/nokolexbor/node.rb', line 241 def matches?(selector) ancestors.last.css(selector).any? { |node| node == self } end |
#name ⇒ String Also known as: node_name
Get the name of this Node
898 899 900 901 902 903 904 905 |
# File 'ext/nokolexbor/nl_node.c', line 898
static VALUE
nl_node_name(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
size_t len;
const lxb_char_t *name = lxb_dom_node_name_qualified(node, &len);
return rb_utf8_str_new((const char *)name, len);
}
|
#next ⇒ Node? Also known as: next_sibling
Get the next sibling node.
761 762 763 764 765 766 |
# File 'ext/nokolexbor/nl_node.c', line 761
static VALUE
nl_node_next(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
return node->next ? nl_rb_node_create(node->next, nl_rb_document_get(self)) : Qnil;
}
|
#next_element ⇒ Element?
Get the next sibling element.
773 774 775 776 777 778 779 780 781 782 783 784 |
# File 'ext/nokolexbor/nl_node.c', line 773
static VALUE
nl_node_next_element(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
while (node->next != NULL) {
node = node->next;
if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) {
return nl_rb_node_create(node, nl_rb_document_get(self));
}
}
return Qnil;
}
|
#node_type ⇒ Integer Also known as: type
Get the type of this Node
1047 1048 1049 1050 1051 |
# File 'ext/nokolexbor/nl_node.c', line 1047
static VALUE
nl_node_get_type(VALUE self)
{
return INT2NUM(nl_rb_node_unwrap(self)->type);
}
|
#nokogiri_at_css(*args) ⇒ Node?
Like #nokogiri_css, but returns the first match.
This method uses libxml2 as the selector engine. It works the same way as Nokogiri::Node#at_css.
372 373 374 |
# File 'lib/nokolexbor/node.rb', line 372 def nokogiri_at_css(*args) nokogiri_css(*args).first end |
#nokogiri_css(*args) ⇒ NodeSet
Search this object for CSS rules
. rules
must be one or more CSS selectors. It supports a mixed syntax of CSS selectors and XPath.
This method uses libxml2 as the selector engine. It works the same way as Nokogiri::Node#css.
358 359 360 361 362 |
# File 'lib/nokolexbor/node.rb', line 358 def nokogiri_css(*args) rules, handler, ns, _ = extract_params(args) nokogiri_css_internal(self, rules, handler, ns) end |
#outer_html(*args) ⇒ String Also known as: to_html, serialize, to_s
Serialize this Node to HTML, also known as outer_html.
561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 |
# File 'ext/nokolexbor/nl_node.c', line 561
static VALUE
nl_node_outer_html(int argc, VALUE *argv, VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lexbor_str_t str = {0};
VALUE options;
lxb_status_t status;
size_t indent = 0;
rb_scan_args(argc, argv, "01", &options);
if (TYPE(options) == T_HASH) {
VALUE rb_indent = rb_hash_aref(options, ID2SYM(rb_intern("indent")));
if (!NIL_P(rb_indent)) {
indent = NUM2INT(rb_indent);
}
}
if (indent > 0) {
status = lxb_html_serialize_pretty_tree_str(node, 0, 0, &str);
} else {
status = lxb_html_serialize_tree_str(node, &str);
}
if (status != LXB_STATUS_OK) {
if (str.data != NULL) {
lexbor_str_destroy(&str, node->owner_document->text, false);
}
nl_raise_lexbor_error(status);
}
if (str.data != NULL) {
VALUE ret = rb_utf8_str_new((const char *)str.data, str.length);
lexbor_str_destroy(&str, node->owner_document->text, false);
return ret;
}
return Qnil;
}
|
#parent ⇒ Node?
Get the parent node.
719 720 721 722 723 724 |
# File 'ext/nokolexbor/nl_node.c', line 719
static VALUE
nl_node_parent(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
return node->parent ? nl_rb_node_create(node->parent, nl_rb_document_get(self)) : Qnil;
}
|
#parent=(parent_node) ⇒ Object
Set the parent Node of this Node.
292 293 294 |
# File 'lib/nokolexbor/node.rb', line 292 def parent=(parent_node) parent_node.add_child(self) end |
#parse(html) ⇒ NodeSet
Parse html
as a document fragment within the context of this node.
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 |
# File 'ext/nokolexbor/nl_node.c', line 936
static VALUE
nl_node_parse(VALUE self, VALUE html)
{
Check_Type(html, T_STRING);
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_document_t *doc = node->owner_document;
lxb_dom_node_t *frag_root = nl_node_parse_fragment(doc, lxb_dom_interface_element(node), (lxb_char_t *)RSTRING_PTR(html), RSTRING_LEN(html));
lexbor_array_t *array = lexbor_array_create();
while (frag_root->first_child != NULL) {
lxb_dom_node_t *child = frag_root->first_child;
lxb_dom_node_remove(child);
lexbor_array_push(array, child);
}
lxb_dom_node_destroy(frag_root);
return nl_rb_node_set_create_with_data(array, nl_rb_document_get(self));
}
|
#path ⇒ String
Returns The path associated with this Node.
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 |
# File 'ext/nokolexbor/nl_node.c', line 1151
static VALUE
nl_node_path(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
char* path = nl_xmlGetNodePath(node);
if (path == NULL) {
return Qnil;
}
VALUE ret = rb_utf8_str_new_cstr(path);
nl_xmlFree(path);
return ret;
}
|
#prepend_child(node) ⇒ Node, NodeSet
Add node
as the first child of this Node.
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/nokolexbor/node.rb', line 220 def prepend_child(node) if (first = children.first) # Mimic the error add_child would raise. raise "Document already has a root node" if document? && !(node.comment? || node.processing_instruction?) first.add_sibling(:previous, node) else add_child(node) end end |
#previous ⇒ Node? Also known as: previous_sibling
Get the previous sibling node.
731 732 733 734 735 736 |
# File 'ext/nokolexbor/nl_node.c', line 731
static VALUE
nl_node_previous(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
return node->prev ? nl_rb_node_create(node->prev, nl_rb_document_get(self)) : Qnil;
}
|
#previous_element ⇒ Element?
Get the previous sibling element.
743 744 745 746 747 748 749 750 751 752 753 754 |
# File 'ext/nokolexbor/nl_node.c', line 743
static VALUE
nl_node_previous_element(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
while (node->prev != NULL) {
node = node->prev;
if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) {
return nl_rb_node_create(node, nl_rb_document_get(self));
}
}
return Qnil;
}
|
#processing_instruction? ⇒ Boolean
Returns true if this is a ProcessingInstruction.
36 37 38 |
# File 'lib/nokolexbor/node.rb', line 36 def processing_instruction? type == PI_NODE end |
#remove ⇒ Node Also known as: unlink
Remove this node from its current context.
846 847 848 849 850 851 852 |
# File 'ext/nokolexbor/nl_node.c', line 846
static VALUE
nl_node_remove(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
lxb_dom_node_remove(node);
return self;
}
|
#remove_attr(name) ⇒ Boolean Also known as: delete, remove_attribute
Remove the attribute named name
.
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
# File 'ext/nokolexbor/nl_node.c', line 313
static VALUE
nl_node_remove_attr(VALUE self, VALUE rb_attr)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return Qfalse;
}
VALUE rb_attr_s = rb_String(rb_attr);
const char *attr_c = RSTRING_PTR(rb_attr_s);
size_t attr_len = RSTRING_LEN(rb_attr_s);
lxb_dom_element_t *element = lxb_dom_interface_element(node);
lxb_status_t status = lxb_dom_element_remove_attribute(element, (const lxb_char_t *)attr_c, attr_len);
if (status != LXB_STATUS_OK) {
nl_raise_lexbor_error(status);
}
return Qtrue;
}
|
#remove_class(names = nil) ⇒ Node
Remove CSS classes from this node. Any CSS class names in css_classes
that exist in this node’s “class” attribute are removed, including any multiple entries.
If no CSS classes remain after this operation, or if css_classes
is nil
, the “class” attribute is deleted from the node.
This is a convenience function and is equivalent to:
node.kwattr_remove("class", css_classes)
527 528 529 |
# File 'lib/nokolexbor/node.rb', line 527 def remove_class(names = nil) kwattr_remove("class", names) end |
#replace(node) ⇒ Node, NodeSet
Replace this Node with node
.
261 262 263 264 265 |
# File 'lib/nokolexbor/node.rb', line 261 def replace(node) ret = add_sibling(:previous, node) remove ret end |
#search(*args) ⇒ NodeSet Also known as: /
Search this object for paths
. paths
must be one or more XPath or CSS selectors.
405 406 407 408 409 410 411 412 413 |
# File 'lib/nokolexbor/node.rb', line 405 def search(*args) paths, handler, ns, binds = extract_params(args) if paths.size == 1 && !LOOKS_LIKE_XPATH.match?(paths.first) return css(paths.first) end xpath(*(paths + [ns, handler, binds].compact)) end |
#source_location ⇒ Integer
Returns The node’s location at the source HTML. Returns 0 if the node is not parsed from a HTML string.
1141 1142 1143 1144 1145 1146 |
# File 'ext/nokolexbor/nl_node.c', line 1141
static VALUE
nl_node_source_location(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
return ULONG2NUM(node->source_location);
}
|
#swap(node) ⇒ Node
Swap this Node for node
.
274 275 276 277 |
# File 'lib/nokolexbor/node.rb', line 274 def swap(node) replace(node) self end |
#text? ⇒ Boolean
Returns true if this is a Text.
41 42 43 |
# File 'lib/nokolexbor/node.rb', line 41 def text? type == TEXT_NODE end |
#traverse { ... } ⇒ Object
Traverse self and all children.
233 234 235 236 |
# File 'lib/nokolexbor/node.rb', line 233 def traverse(&block) children.each { |j| j.traverse(&block) } yield(self) end |
#value?(value) ⇒ Boolean
Returns true if this Node’s attributes include <value>.
297 298 299 |
# File 'lib/nokolexbor/node.rb', line 297 def value?(value) values.include?(value) end |
#values ⇒ Array<String>
Get the attribute values of this Node.
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
# File 'ext/nokolexbor/nl_node.c', line 654
static VALUE
nl_node_values(VALUE self)
{
lxb_dom_node_t *node = nl_rb_node_unwrap(self);
VALUE ary_values = rb_ary_new();
if (node->type != LXB_DOM_NODE_TYPE_ELEMENT) {
return ary_values;
}
lxb_dom_attr_t *attr = lxb_dom_element_first_attribute(lxb_dom_interface_element(node));
while (attr != NULL) {
size_t tmp_len;
const lxb_char_t *tmp = lxb_dom_attr_value(attr, &tmp_len);
if (tmp != NULL) {
rb_ary_push(ary_values, rb_utf8_str_new((const char *)tmp, tmp_len));
} else {
rb_ary_push(ary_values, rb_str_new("", 0));
}
attr = lxb_dom_element_next_attribute(attr);
}
return ary_values;
}
|
#wrap(node) ⇒ Node
Wrap this Node with another node.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/nokolexbor/node.rb', line 122 def wrap(node) case node when String new_parent = fragment(node).child when DocumentFragment new_parent = node.child when Node new_parent = node.dup else raise ArgumentError, "Requires a String or Node argument, and cannot accept a #{node.class}" end if parent add_sibling(:next, new_parent) else new_parent.remove end new_parent.add_child(self) self end |
#write_to(io, *options) ⇒ Object Also known as: write_html_to
Serialize Node and write to io
.
655 656 657 |
# File 'lib/nokolexbor/node.rb', line 655 def write_to(io, *) io.write(to_html(*)) end |
#xpath(*args) ⇒ NodeSet
Search this node for XPath paths
. paths
must be one or more XPath queries.
It works the same way as Nokogiri::Node#xpath.
385 386 387 388 389 |
# File 'lib/nokolexbor/node.rb', line 385 def xpath(*args) paths, handler, ns, binds = extract_params(args) xpath_internal(self, paths, handler, ns, binds) end |