XML::Grove::Visitor like interfaces.
new(child1, child2, …)
child?: String or Node
# File lib/xml/dom/core.rb, line 224 def initialize(*children) @parent = nil @children = nil self.childNodes = children if children.length > 0 end
# File lib/xml/dom/core.rb, line 393 def +(node) [self, node] end
# File lib/xml/dom2/node.rb, line 561 def <=>(node) ancestors1 = [self] ancestors2 = [node] p = self while p = p.parentNode ancestors1.unshift(p) end p = node while p = p.parentNode ancestors2.unshift(p) end raise "different document" unless ancestors1[0].equal?(ancestors2[0]) ret = 0 i = 0 for i in 1...ancestors1.size next if ancestors1[i].equal?(ancestors2[i]) return 1 if ancestors2[i].nil? children = ancestors1[i - 1].childNodes.to_a return children.index(ancestors1[i]) - children.index(ancestors2[i]) end return -1 if ancestors2.size > i + 1 0 end
# File lib/xml/dom2/node.rb, line 557 def ==(node) equal?(node) end
# File lib/xml/dom/core.rb, line 384 def [](index) @children[index] end
# File lib/xml/dom/core.rb, line 372 def []=(index, nodes) @children[index..index] = nodes @children.each do |child| child.parentNode = self end if @children end
# File lib/xml/dom2/xpath.rb, line 284 def __collectAncestorNS(ns = {}) node = self while node prefix = node.prefix uri = node.namespaceURI ns[prefix] = uri unless ns.has_key?(prefix) node = node.parentNode end end
# File lib/xml/dom2/xpath.rb, line 274 def __collectDescendatNS(ns = {}) childNodes.each do |node| next if node.nodeType != ELEMENT_NODE prefix = node.prefix uri = node.namespaceURI ns[prefix] = uri unless ns.has_key?(prefix) node.__collectDescendatNS(ns) end end
# File lib/xml/dom/core.rb, line 703 def __sibling(reverse, only_appeared_before_self) return if @parent.nil? self_appeared = false @parent.childNodes.reversible_each(reverse) do |node| if node == self self_appeared = true next end if only_appeared_before_self break if self_appeared yield node else # only appeared after self yield node if self_appeared end end end
# File lib/xml/dom/core.rb, line 695 def _ancestor(reverse = false) return if @parent.nil? yield @parent if !reverse @parent._ancestor(reverse) do |node| yield node end yield @parent if reverse end
# File lib/xml/dom/core.rb, line 504 def _checkNode(node) raise DOMException.new(DOMException::HIERARCHY_REQUEST_ERR) end
# File lib/xml/dom/core.rb, line 676 def _child(reverse = false) return if @children.nil? @children.reversible_each(reverse) do |child| yield child end end
# File lib/xml/dom/core.rb, line 684 def _descendant(reverse = false) return if @children.nil? @children.reversible_each(reverse) do |child| yield child child._descendant(reverse) do |node| yield node end end end
# File lib/xml/dom/core.rb, line 751 def _following(reverse = false) return if @parent.nil? next_sib = nextSibling if next_sib next_sib._following(reverse) {|node| yield node} if reverse yield next_sib next_sib._descendant(reverse) {|node| yield node} next_sib._following(reverse) {|node| yield node} if !reverse else @parent._following(reverse) {|node| yield node} if reverse yield @parent @parent._following(reverse) {|node| yield node} if !reverse end end
# File lib/xml/dom/core.rb, line 728 def _fsibling(reverse = false) __sibling(reverse, reverse) do |sib| yield sib end end
# File lib/xml/dom/core.rb, line 486 def _getChildIndex(node) index = 0 @children.each do |child| if child == node return index end index += 1 end nil end
# File lib/xml/dom/core.rb, line 651 def _getMyLocation(parent) index = parent._getChildIndex(self) if !index.nil? "child(#{index + 1},#all)" else nil end end
# File lib/xml/dom2/xpath.rb, line 306 def _getMyLocationInXPath(parent) n = parent.childNodes.index(self) "node()[#{n + 1}]" end
# File lib/xml/dom/core.rb, line 954 def _getNodeByAbsoluteLocationTerm(location) case location when 'root()', '' if nodeType == DOCUMENT_NODE root = documentElement elsif !ownerDocument.nil? root = ownerDocument.documentElement end root = self if root.nil? return root when 'origin()' return self when /^id\(([^\)]*)\)$/ value = $1 raise "invalid id value: #{value}" if value !~ Spec::Name return _searchID(value) when /^html\(([^\)]*)\)$/ value = $1 return getNodesByXPointer("root().descendant(1,A,NAME,\"#{value}\")")[0] else raise "unknown keyword: #{location}" end end
# File lib/xml/dom/core.rb, line 508 def _insertNodes(index, node) if node.nodeType == DOCUMENT_FRAGMENT_NODE node.childNodes.to_a.each_with_index do |n, i| if index == -1 _insertNodes(-1, n) else _insertNodes(index + i, n) end end elsif node.is_a?(Node) ## to be checked _checkNode(node) node._removeFromTree if index == -1 @children.push(node) else @children[index, 0] = node end node.parentNode = self else raise ArgumentError, "invalid value for Node" end end
# File lib/xml/dom/core.rb, line 767 def _matchAttribute?(attr, value) case value when '*' return !attr.nil? when '#IMPLIED' return attr.nil? else return false if attr.nil? end case value when /^"([^"]*)"$/, /^'([^']*)'$/ ignore_case = false value = $1 when Spec::Name ignore_case = true else raise "invalid attribute value: #{value}" end if ignore_case return attr.nodeValue.downcase == value.downcase else return attr.nodeValue == value end end
# File lib/xml/dom/core.rb, line 850 def _matchNode?(node, ntype, attributes) _matchNodeType?(node, ntype) && _matchNodeAttributes?(node, attributes) end
# File lib/xml/dom/core.rb, line 794 def _matchNodeAttributes?(node, attributes) return true if attributes.nil? raise TypeError if !attributes.is_a?(Hash) return true if attributes.length == 0 return false if node.nodeType != ELEMENT_NODE attributes.each do |name, value| case name when '*' return catch(:match) { node.attributes.each do |attr| throw(:match, true) if _matchAttribute?(attr, value) end false } when Spec::Name attr = node.attributes[name] unless node.attributes.nil? return _matchAttribute?(attr, value) else raise "invalid attribute name: '#{name}'" end end end
# File lib/xml/dom/core.rb, line 819 def _matchNodeType?(node, ntype) case ntype when '#element' return (node.nodeType == ELEMENT_NODE) when '#pi' return (node.nodeType == PROCESSING_INSTRUCTION_NODE) when '#comment' return (node.nodeType == COMMENT_NODE) when '#text' return (node.nodeType == TEXT_NODE || node.nodeType == CDATA_SECTION_NODE) when '#cdata' return (node.nodeType == CDATA_SECTION_NODE) when '#all' case node.nodeType when ELEMENT_NODE, PROCESSING_INSTRUCTION_NODE, COMMENT_NODE, TEXT_NODE, CDATA_SECTION_NODE return true else return false end when /^#/ raise "unknown node type: '#{ntype}'" when Spec::Name return (node.nodeType == ELEMENT_NODE && node.nodeName == ntype) else raise "invalid element type: '#{ntype}'" end end
# File lib/xml/dom/core.rb, line 906 def _nodesByLocationTerms(location, pre_keyword = nil) if location !~ /^([a-z]*)\(([^)]*)\)(\.(.+))?$/ raise "invalid location: \"#{location}\"" end keyword = $1 args = $2 rest = $4 ## omitted keyword keyword = pre_keyword if keyword == '' if keyword.nil? raise "cannot determine preceding keyword: \"#{location}\"" end case keyword when 'child', 'descendant', 'ancestor', 'psibling', 'fsibling', 'preceding', 'following' # relative location term _nodesByRelativeLocationTerm("#{keyword}(#{args})") do |node| if rest.nil? yield node else node._nodesByLocationTerms(rest, keyword) do |n| yield n end end end when 'attr' # attribute location term if args !~ Spec::Name raise "invalid attribute name: '#{args}'" end attr = attributes[args] value = (attr.nil? ? nil : Text.new(attr.nodeValue)) if rest.nil? yield value elsif !value.nil? value._nodesByLocationTerms(rest) do |node| yield node end end when 'span', 'string' raise "unsupported keyword: '#{keyword}'" else raise "unknown keyword: '#{keyword}'" end end
# File lib/xml/dom/core.rb, line 856 def _nodesByRelativeLocationTerm(location) if location !~ /^([a-z]+)\(([^\)]*)\)$/ raise "invalid relative location: '#{location}'" end keyword = $1 args = $2.split(/,/) number = args.shift ntype = args.shift ntype = '#element' if ntype.nil? attributes = args reverse = false # check instance number case number when nil, '' raise "missing instance number: '#{location}'" when 'all' when Spec::Instance number = number.to_i if number < 0 reverse = true number = -number end else raise "unknown instance number: '#{number}'" end # check attributes if attributes.length % 2 != 0 raise " missing attribute value: '#{location}'" end attributes = Hash[*attributes] # iterate over nodes specified with keyword i = 0 self.send("_#{keyword}", reverse) do |node| next unless _matchNode?(node, ntype, attributes) if number == "all" yield node else i += 1 if i >= number yield node break end end end end
# File lib/xml/dom/core.rb, line 735 def _preceding(reverse = false) return if @parent.nil? prev_sib = previousSibling if prev_sib prev_sib._preceding(reverse) {|node| yield node} if reverse yield prev_sib prev_sib._descendant(!reverse) {|node| yield node} prev_sib._preceding(reverse) {|node| yield node} if !reverse else @parent._preceding(reverse) {|node| yield node} if reverse yield @parent @parent._preceding(reverse) {|node| yield node} if !reverse end end
# File lib/xml/dom/core.rb, line 721 def _psibling(reverse = false) __sibling(!reverse, reverse) do |sib| yield sib end end
# File lib/xml/dom/core.rb, line 497 def _removeFromTree parent = parentNode if parent parent.removeChild(self) end end
# File lib/xml/dom/core.rb, line 533 def _removeNode(index, node) @children[index, 1] = nil node.parentNode = nil end
get the Node object by IDs
# File lib/xml/dom/core.rb, line 627 def _searchID(value, ids = nil) if ids.nil? doc = nil if nodeType == DOCUMENT_NODE doc = self elsif !ownerDocument.nil? doc = ownerDocument else return nil end ids = doc._getIDAttrs end if nodeType == ELEMENT_NODE && _getIDVals(ids).include?(value) return self elsif !@children.nil? @children.each do |node| if !(match = node._searchID(value, ids)).nil? return match end end end return nil end
# File lib/xml/dom/visitor.rb, line 110 def accept(visitor, *rest) typename = self.class.to_s.sub(/.*?([^:]+)$/, '\1') visitor.send("visit_" + typename, self, *rest) end
# File lib/xml/dom/visitor.rb, line 120 def accept_name(visitor, *rest) if nodeType == ELEMENT_NODE name_method = "visit_name_" + nodeName visitor.send(name_method, self, *rest) else self.accept(visitor, *rest) end end
# File lib/xml/dom/core.rb, line 609 def appendChild(newChild) @children = NodeList.new if !@children _insertNodes(-1, newChild) end
# File lib/xml/dom/core.rb, line 359 def attributes nil end
# File lib/xml/dom/core.rb, line 311 def childNodes if iterator? @children.each do |child| yield(child) end if @children else return @children if !@children.nil? @children = NodeList.new end end
# File lib/xml/dom/core.rb, line 328 def childNodes=(p) if @children.nil? @children = NodeList.new else @children.to_a.clear end if p.nil? || (p.is_a?(Array) && p.length == 0) return end p.flatten! p.each do |child| if child.is_a?(String) c = Text.new(child) @children.push(c) c.parentNode = self elsif child.is_a?(Node) @children.push(child) child.parentNode = self else raise "parameter error" end end if p end
# File lib/xml/dom/visitor.rb, line 134 def children_accept(visitor, *rest) ret = [] @children && @children.each { |node| ret.push(node.accept(visitor, *rest)) } ret end
# File lib/xml/dom/visitor.rb, line 147 def children_accept_name(visitor, *rest) ret = [] @children && @children.each { |node| ret.push(node.accept_name(visitor, *rest)) } ret end
# File lib/xml/dom/core.rb, line 1044 def cloneNode(deep = true, *args) ret = self.class.new(*args) if (deep) @children.each do |child| ret.appendChild(child.cloneNode(true)) end end if @children ret end
# File lib/xml/dom/core.rb, line 411 def dump(depth = 0) print ' ' * depth * 2 print nodeName + "\n" @children.each do |child| child.dump(depth + 1) end if @children end
# File lib/xml/dom/visitor.rb, line 162 def each sibstack = [] siblings = [ self ] while true if siblings.length == 0 break if sibstack.length == 0 siblings = sibstack.pop next end node = siblings.shift yield(node) children = node.childNodes if !children.nil? sibstack.push(siblings) siblings = children.to_a.dup end end end
# File lib/xml/dom/core.rb, line 435 def firstChild return nil if !@children || @children.length == 0 return @children[0] end
# File lib/xml/dom/digest.rb, line 31 def getDigest(algorithm = Digest::MD5, force = false) nil end
# File lib/xml/dom2/xpath.rb, line 294 def getNodesByXPath(xpath, ns = {}) xpath = XMLScan::XPath.compile(xpath) unless xpath.is_a? XMLScan::XPath if ns.length == 0 ## collect namespaces __collectAncestorNS(ns) __collectDescendatNS(ns) end ret = xpath.call(XPath::DOM::Context.new(self, ns)) raise "return value is not NodeSet" unless ret.is_a? Array ret end
# File lib/xml/dom/core.rb, line 984 def getNodesByXPointer(pointer) if pointer !~ /^([a-z]+)\(([^)]*)\)(\.(.+))?$/ raise "invalid XPointer: \"#{pointer}\"" end keyword = $1 args = $2 rest = $4 case keyword when 'root', 'origin', 'id', 'html' src = _getNodeByAbsoluteLocationTerm("#{keyword}(#{args})") else src = _getNodeByAbsoluteLocationTerm("root()") rest = pointer end ret = NodeList.new if src.nil? # no match elsif rest.nil? yield src if iterator? ret << src else src._nodesByLocationTerms(rest) do |node| yield node if iterator? ret << node end end ret end
# File lib/xml/dom2/node.rb, line 532 def hasAttributes(); false; end
# File lib/xml/dom/core.rb, line 621 def hasChildNodes !@children.nil? && @children.length > 0 end
# File lib/xml/dom/core.rb, line 559 def insertBefore(newChild, refChild) if @children.nil? || @children.length == 0 raise DOMException.new(DOMException::NOT_FOUND_ERR) end index = _getChildIndex(refChild) raise DOMException.new(DOMException::NOT_FOUND_ERR) if !index _insertNodes(index, newChild) end
# File lib/xml/dom/core.rb, line 424 def inspect "#<#{self.class}: #{self.nodeName}>" end
# File lib/xml/dom2/node.rb, line 509 def isSupported(feature, version) if (feature =~ /^XML$/ || feature =~ /^Core$/) && (version.nil? || version == "1.0" || version == "2.0") return true end false end
# File lib/xml/dom/core.rb, line 447 def lastChild return nil if !@children || @children.length == 0 return @children[-1] end
# File lib/xml/dom2/node.rb, line 529 def localname; nil; end
# File lib/xml/dom2/xpath.rb, line 311 def makeXPath dst = [] node = self while parent = node.parentNode dst.push node._getMyLocationInXPath(parent) node = parent end dst.reverse! '/' + dst.join('/') end
# File lib/xml/dom/core.rb, line 665 def makeXPointer(use_id = true) if use_id && !attributes.nil? && !(idvals = _getIDVals).empty? "id(#{idvals[0]})" elsif @parent.nil? || @parent.nodeType == DOCUMENT_NODE "root()" else @parent.makeXPointer(use_id) + "." + self._getMyLocation(@parent) end end
# File lib/xml/dom2/node.rb, line 518 def namespaceURI; nil; end
# File lib/xml/dom/core.rb, line 476 def nextSibling return nil if !@parent nexts = nil @parent.childNodes.reverse.each do |child| return nexts if child == self nexts = child end nil end
# File lib/xml/dom/core.rb, line 274 def nodeName "#node" end
# File lib/xml/dom/core.rb, line 262 def nodeType NODE_NODE end
# File lib/xml/dom/core.rb, line 290 def nodeValue; nil; end
# File lib/xml/dom/core.rb, line 299 def nodeValue=(p) ## no effect end
Floating objects are not owned by any documents.
# File lib/xml/dom/core.rb, line 1023 def ownerDocument return @ownerDocument if @ownerDocument parent = self.parentNode return nil if parent.nil? if parent.nodeType == DOCUMENT_NODE return parent else return parent.ownerDocument end end
# File lib/xml/dom/core.rb, line 1034 def ownerDocument=(document); @ownerDocument = document; end
# File lib/xml/dom/core.rb, line 240 def parentNode @parent end
# File lib/xml/dom/core.rb, line 250 def parentNode=(p) @parent = p end
# File lib/xml/dom2/node.rb, line 521 def prefix; nil; end
# File lib/xml/dom2/node.rb, line 524 def prefix=(prefix); ## no effect end
# File lib/xml/dom/core.rb, line 459 def previousSibling return nil if !@parent prev = nil @parent.childNodes do |child| return prev if child == self prev = child end nil end
# File lib/xml/dom/core.rb, line 592 def removeChild(oldChild) if @children.nil? || @children.length == 0 raise DOMException.new(DOMException::NOT_FOUND_ERR) end index = _getChildIndex(oldChild) raise DOMException.new(DOMException::NOT_FOUND_ERR) if !index _removeNode(index, oldChild) oldChild end
# File lib/xml/dom/core.rb, line 575 def replaceChild(newChild, oldChild) if @children.nil? || @children.length == 0 raise DOMException.new(DOMException::NOT_FOUND_ERR) end index = _getChildIndex(oldChild) raise DOMException.new(DOMException::NOT_FOUND_ERR) if !index _removeNode(index, oldChild) _insertNodes(index, newChild) end
# File lib/xml/dom/core.rb, line 402 def to_s @children.to_s end
if attribute 'xml:space' is 'preserve', don't trim any white spaces
# File lib/xml/dom/core.rb, line 1062 def trim(preserve = false) return nil if @children.nil? children = @children.to_a.dup children.each do |child| if !preserve && (child.nodeType == TEXT_NODE || child.nodeType == CDATA_SECTION_NODE) if child.trim == "" self.removeChild(child) end else child.trim(preserve) end end nil end