Class: VCDOM::Element
- Inherits:
-
Node
- Object
- Node
- VCDOM::Element
- Includes:
- Parent, Child
- Defined in:
- lib/vcdom/element.rb
Direct Known Subclasses
Instance Method Summary collapse
- #append_child(new_child) ⇒ Object
-
#attributes ⇒ Object
attributes.
-
#child_element_count ⇒ Object
The current number of child nodes of that element which are of nodeType
ELEMENT_NODE
. - #each_attr_node ⇒ Object
-
#first_element_child ⇒ Object
The first child node of that element which is of nodeType
ELEMENT_NODE
, as an Element object. -
#get_attribute(name) ⇒ Object
Retrieves an attribute value by name.
- #get_attribute_ns(namespace_uri, local_name) ⇒ Object
-
#initialize(doc, tag_name) ⇒ Element
constructor
:nodoc:.
-
#last_element_child ⇒ Object
The last child node of that element which is of nodeType
ELEMENT_NODE
, as an Element object. - #local_name ⇒ Object
-
#next_element_sibling ⇒ Object
The sibling node of that element which most immediately follows that element in document order, and which is of nodeType
ELEMENT_NODE
, as an Element object. - #node_type ⇒ Object
-
#normalize_namespaces ⇒ Object
void Element.normalizeNamespaces().
-
#previous_element_sibling ⇒ Object
The sibling node of that element which most immediately precedes that element in document order, and which is of nodeType
ELEMENT_NODE
, as an Element object. - #set_attribute(name, value) ⇒ Object
-
#set_attribute_node(new_attr) ⇒ Object
setAttributeNode Adds a new attribute node.
-
#set_attribute_node_ns(new_attr) ⇒ Object
setAttributeNodeNS introduced in DOM Level 2 Adds a new attribute.
- #set_attribute_ns(namespace_uri, qualified_name, value) ⇒ Object
- #tag_name ⇒ Object (also: #node_name)
Methods included from Child
#_leave_from_tree, #_set_next_sibling, #_set_parent_node, #initialize_child, #next_sibling, #parent_node, #previous_sibling
Constructor Details
#initialize(doc, tag_name) ⇒ Element
:nodoc:
14 15 16 17 18 19 20 21 |
# File 'lib/vcdom/element.rb', line 14 def initialize( doc, tag_name ) # :nodoc: initialize_parent() super( doc ) @local_name = tag_name # attributes @attr_nodes = Array.new() @attr_node_map = AttrNodeMap.new( @attr_nodes ) end |
Instance Method Details
#append_child(new_child) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/vcdom/element.rb', line 36 def append_child( new_child ) # ノードのタイプチェックなど if not new_child.is_a? Node then raise ArgumentError.new( "the argument [#{new_child}] is not an object of the expected class." ) end # Element, Text, Comment, ProcessingInstruction, CDATASection, EntityReference case new_child.node_type when ELEMENT_NODE, TEXT_NODE, CDATA_SECTION_NODE, ENTITY_REFERENCE_NODE, PROCESSING_INSTRUCTION_NODE, COMMENT_NODE then # OK else # ERROR raise "ERROR" end _append_child( new_child ) end |
#attributes ⇒ Object
attributes
53 54 55 |
# File 'lib/vcdom/element.rb', line 53 def attributes @attr_node_map end |
#child_element_count ⇒ Object
The current number of child nodes of that element which are of nodeType ELEMENT_NODE
. This value is not stored, but calculated when you access this attribute.
407 408 409 410 411 412 413 414 415 |
# File 'lib/vcdom/element.rb', line 407 def child_element_count num = 0 self.each_child_node do |n| if n.node_type == ELEMENT_NODE then num += 1 end end return num end |
#each_attr_node ⇒ Object
56 57 58 59 60 |
# File 'lib/vcdom/element.rb', line 56 def each_attr_node @attr_nodes.each do |n| yield n end end |
#first_element_child ⇒ Object
The first child node of that element which is of nodeType ELEMENT_NODE
, as an Element object. If the element on which this attribute is accessed does not have any child nodes, or if none of those child nodes are element nodes, then this attribute return nil
. (defiend at W3C Element Traversal Specification)
347 348 349 350 351 352 353 354 355 356 |
# File 'lib/vcdom/element.rb', line 347 def first_element_child n = self.first_child while n do if n.node_type == ELEMENT_NODE then break end n = n.next_sibling end return n end |
#get_attribute(name) ⇒ Object
Retrieves an attribute value by name.
88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vcdom/element.rb', line 88 def get_attribute( name ) @attr_nodes.each do |attr| if attr.name == name then #////////////////////////// # 変更する #////////////////////////// return attr.value end end return "" end |
#get_attribute_ns(namespace_uri, local_name) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/vcdom/element.rb', line 123 def get_attribute_ns( namespace_uri, local_name ) @attr_nodes.each do |attr| if attr.namespace_uri == namespace_uri and attr.local_name == local_name then #////////////////////////// # 変更する #////////////////////////// return attr.value end end return "" end |
#last_element_child ⇒ Object
The last child node of that element which is of nodeType ELEMENT_NODE
, as an Element object. If the element on which this attribute is accessed does not have any child nodes, or if none of those child nodes are element nodes, then this attribute return nil
. (defiend at W3C Element Traversal Specification)
362 363 364 365 366 367 368 369 370 371 |
# File 'lib/vcdom/element.rb', line 362 def last_element_child n = self.last_child while n do if n.node_type == ELEMENT_NODE then break end n = n.previous_sibling end return n end |
#local_name ⇒ Object
32 33 34 |
# File 'lib/vcdom/element.rb', line 32 def local_name nil end |
#next_element_sibling ⇒ Object
The sibling node of that element which most immediately follows that element in document order, and which is of nodeType ELEMENT_NODE
, as an Element object. If the element on which this attribute is accessed does not have any following sibling nodes, or if none of those following sibling nodes are element nodes, then this attribute must return nil
. (defiend at W3C Element Traversal Specification)
394 395 396 397 398 399 400 401 402 403 |
# File 'lib/vcdom/element.rb', line 394 def next_element_sibling n = self.next_sibling while n do if n.node_type == ELEMENT_NODE then break end n = n.next_sibling end return n end |
#node_type ⇒ Object
23 24 25 |
# File 'lib/vcdom/element.rb', line 23 def node_type ELEMENT_NODE end |
#normalize_namespaces ⇒ Object
void Element.normalizeNamespaces()
160 161 162 163 164 165 166 167 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 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/vcdom/element.rb', line 160 def normalize_namespaces() # non-namespace Attrs of Element non_ns_attrs = Array.new() # Pick up local namespace declarations # for ( all DOM Level 2 valid local namespace declaration attributes of Element ) { # if (the namespace declaration is invalid) { # Note: The prefix xmlns is used only to declare namespace bindings and # is by definition bound to the namespace name http://www.w3.org/2000/xmlns/. # It must not be declared. No other prefix may be bound to this namespace name. # ==> Report an error. # } else { # ==> Record the namespace declaration # } # } #ns = Hash.new() @attr_nodes.each do |n| if n.name == "xmlns" then # ns[nil] = n[0].data elsif n.prefix == "xmlns" then # ns[n.local_name.intern] = n[0].data else non_ns_attrs << n end end # Fixup element's namespace if self.namespace_uri then # when Element's namespaceURI is not nil # prefix / ns ペアが既にスコープ内に存在するかどうかの確認 # この flag チェックは変更しないとダメかも... flag = false if self.prefix.nil? then #/////////////////////////////////// # is_default_namespace だとダメー #/////////////////////////////////// #if self.is_default_namespace( self.namespace_uri ) then # flag = true #end n = self loop do if n.nil? then break elsif n.node_type == ELEMENT_NODE then if n.get_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns" ) == self.namespace_uri then flag = true break end end n = n.parent_node end else #/////////////////////////////////// # lookup_namespace_uri だとダメー #/////////////////////////////////// #if self.lookup_namespace_uri( self.prefix ) == self.namespace_uri then # flag = true #end if self.prefix == "xml" then # ok? flag = true else n = self loop do if n.nil? then break elsif n.node_type == ELEMENT_NODE then if n.get_attribute_ns( "http://www.w3.org/2000/xmlns/", self.prefix ) == self.namespace_uri then flag = true break end end n = n.parent_node end end end if flag then # when Element's prefix/namespace pair (or default namespace, if no prefix) are within the scope of a binding # ==> do nothing, declaration in scope is inherited # See section "B.1.1: Scope of a binding" for an example else # ==> Create a local namespace declaration attr for this namespace, # with Element's current prefix (or a default namespace, if # no prefix). If there's a conflicting local declaration # already present, change its value to use this namespace. # See section "B.1.2: Conflicting namespace declaration" for an example # // NOTE that this may break other nodes within this Element's # // subtree, if they're already using this prefix. # // They will be repaired when we reach them. if self.prefix.nil? then self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns", self.namespace_uri ) else self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{self.prefix}", self.namespace_uri ) end end else # when Element has no namespace URI: if self.local_name.nil? then # when Element's localName is null # // DOM Level 1 node # ==> if in process of validation against a namespace aware schema # (i.e XML Schema) report a fatal error: the processor can not recover # in this situation. # Otherwise, report an error: no namespace fixup will be performed on this node. else # when Element has no pseudo-prefix if self.prefix.nil? and not self.is_default_namespace( nil ) then # when there's a conflicting local default namespace declaration already present # ==> change its value to use this empty namespace. self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns", "" ) elsif self.prefix and self.lookup_prefix( nil ) == self.prefix then self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{self.prefix}", "" ) end # // NOTE that this may break other nodes within this Element's # // subtree, if they're already using the default namespaces. # // They will be repaired when we reach them. end end # Examine and polish the attributes #for ( all non-namespace Attrs of Element ) non_ns_attrs.each do |attr| if attr.namespace_uri then if attr.prefix == "xml" then # do nothing # when attr has a namespace URI elsif attr.prefix.nil? or self.lookup_namespace_uri( attr.prefix ) != attr.namespace_uri then # when attribute has no prefix (default namespace decl does not apply to attributes) # OR attribute prefix is not declared OR conflict: attribute has a prefix that conflicts with a binding # already active in scope) if not (new_prefix = self.lookup_prefix( attr.namespace_uri )).nil? then # when (namespaceURI matches an in scope declaration of one or more prefixes) # pick the most local binding available; # if there is more than one pick one arbitrarily # ==> change attribute's prefix. attr.prefix = new_prefix else if not attr.prefix.nil? and self.lookup_namespace_uri( attr.prefix ).nil? then # when the current prefix is not null and it has no in scope declaration # ==> declare this prefix self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:#{attr.prefix}", attr.namespace_uri ) else # find a prefix following the pattern "NS" +index (starting at 1) # make sure this prefix is not declared in the current scope. # create a local namespace declaration attribute #==> change attribute's prefix. i = 0 loop do i += 1 if self.lookup_namespace_uri( "NS#{i}" ).nil? then self.set_attribute_ns( "http://www.w3.org/2000/xmlns/", "xmlns:NS#{i}", attr.namespace_uri ) break end end attr.prefix = "NS#{i}" end end end else # attr has no namespace URI if attr.local_name.nil? then # when attr has no localName # = DOM Level 1 node #==> if in process of validation against a namespace aware schema # (i.e XML Schema) report a fatal error: the processor can not recover # in this situation. # Otherwise, report an error: no namespace fixup will be performed on this node. else # attr has no namespace URI and no prefix # no action is required, since attrs don't use default # ==> do nothing end end end # end for-all-Attrs # do this recursively #for ( all child elements of Element ) self.each_child_node do |c| if c.node_type == ELEMENT_NODE then c.normalize_namespaces() end end # end Element.normalizeNamespaces end |
#previous_element_sibling ⇒ Object
The sibling node of that element which most immediately precedes that element in document order, and which is of nodeType ELEMENT_NODE
, as an Element object. If the element on which this attribute is accessed does not have any preceding sibling nodes, or if none of those preceding sibling nodes are element nodes, then this attribute must return nil
. (defiend at W3C Element Traversal Specification)
378 379 380 381 382 383 384 385 386 387 |
# File 'lib/vcdom/element.rb', line 378 def previous_element_sibling n = self.previous_sibling while n do if n.node_type == ELEMENT_NODE then break end n = n.previous_sibling end return n end |
#set_attribute(name, value) ⇒ Object
81 82 83 84 85 86 |
# File 'lib/vcdom/element.rb', line 81 def set_attribute( name, value ) attr = self.owner_document.create_attribute( name ) attr.append_child( self.owner_document.create_text_node( value ) ) self.set_attribute_node( attr ) nil end |
#set_attribute_node(new_attr) ⇒ Object
setAttributeNode Adds a new attribute node. If an attribute with that name (nodeName) is already present in the element, it is replaced by the new one. Replacing an attribute node by itself has no effect. To add a new attribute node with a qualified name and namespace URI, use the setAttributeNodeNS method.
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/vcdom/element.rb', line 69 def set_attribute_node( new_attr ) if new_attr.owner_document != self.owner_document then raise "WRONG_DOCUMENT_ERR" end if not new_attr.owner_element.nil? then raise "INUSE_ATTRIBUTE_ERR" end old_attr = nil @attr_nodes << new_attr new_attr._set_owner_element( self ) old_attr end |
#set_attribute_node_ns(new_attr) ⇒ Object
setAttributeNodeNS introduced in DOM Level 2 Adds a new attribute. If an attribute with that local name and that namespace URI is already present in the element, it is replaced by the new one. Replacing an attribute node by itself has no effect. Per [XML Namespaces], applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace.
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/vcdom/element.rb', line 105 def set_attribute_node_ns( new_attr ) if new_attr.owner_document != self.owner_document then raise "WRONG_DOCUMENT_ERR" end if not new_attr.owner_element.nil? then raise "INUSE_ATTRIBUTE_ERR" end old_attr = nil @attr_nodes << new_attr new_attr._set_owner_element( self ) old_attr end |
#set_attribute_ns(namespace_uri, qualified_name, value) ⇒ Object
117 118 119 120 121 122 |
# File 'lib/vcdom/element.rb', line 117 def set_attribute_ns( namespace_uri, qualified_name, value ) attr = self.owner_document.create_attribute_ns( namespace_uri, qualified_name ) attr.append_child( self.owner_document.create_text_node( value ) ) self.set_attribute_node_ns( attr ) nil end |
#tag_name ⇒ Object Also known as: node_name
27 28 29 |
# File 'lib/vcdom/element.rb', line 27 def tag_name @local_name.to_s() end |