/usr/lib/ruby/vendor_ruby/nokogiri/xml/document.rb is in ruby-nokogiri 1.6.8.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 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 | module Nokogiri
module XML
##
# Nokogiri::XML::Document is the main entry point for dealing with
# XML documents. The Document is created by parsing an XML document.
# See Nokogiri::XML::Document.parse() for more information on parsing.
#
# For searching a Document, see Nokogiri::XML::Searchable#css and
# Nokogiri::XML::Searchable#xpath
#
class Document < Nokogiri::XML::Node
# I'm ignoring unicode characters here.
# See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details.
NCNAME_START_CHAR = "A-Za-z_"
NCNAME_CHAR = NCNAME_START_CHAR + "\\-.0-9"
NCNAME_RE = /^xmlns(:[#{NCNAME_START_CHAR}][#{NCNAME_CHAR}]*)?$/
##
# Parse an XML file.
#
# +string_or_io+ may be a String, or any object that responds to
# _read_ and _close_ such as an IO, or StringIO.
#
# +url+ (optional) is the URI where this document is located.
#
# +encoding+ (optional) is the encoding that should be used when processing
# the document.
#
# +options+ (optional) is a configuration object that sets options during
# parsing, such as Nokogiri::XML::ParseOptions::RECOVER. See the
# Nokogiri::XML::ParseOptions for more information.
#
# +block+ (optional) is passed a configuration object on which
# parse options may be set.
#
# When parsing untrusted documents, it's recommended that the
# +nonet+ option be used, as shown in this example code:
#
# Nokogiri::XML::Document.parse(xml_string) { |config| config.nonet }
#
# Nokogiri.XML() is a convenience method which will call this method.
#
def self.parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
# Give the options to the user
yield options if block_given?
if empty_doc?(string_or_io)
if options.strict?
raise Nokogiri::XML::SyntaxError.new("Empty document")
else
return encoding ? new.tap { |i| i.encoding = encoding } : new
end
end
doc = if string_or_io.respond_to?(:read)
url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
read_io(string_or_io, url, encoding, options.to_i)
else
# read_memory pukes on empty docs
read_memory(string_or_io, url, encoding, options.to_i)
end
# do xinclude processing
doc.do_xinclude(options) if options.xinclude?
return doc
end
# A list of Nokogiri::XML::SyntaxError found when parsing a document
attr_accessor :errors
def initialize *args # :nodoc:
@errors = []
@decorators = nil
end
##
# Create an element with +name+, and optionally setting the content and attributes.
#
# doc.create_element "div" # <div></div>
# doc.create_element "div", :class => "container" # <div class='container'></div>
# doc.create_element "div", "contents" # <div>contents</div>
# doc.create_element "div", "contents", :class => "container" # <div class='container'>contents</div>
# doc.create_element "div" { |node| node['class'] = "container" } # <div class='container'></div>
#
def create_element name, *args, &block
elm = Nokogiri::XML::Element.new(name, self, &block)
args.each do |arg|
case arg
when Hash
arg.each { |k,v|
key = k.to_s
if key =~ NCNAME_RE
ns_name = key.split(":", 2)[1]
elm.add_namespace_definition ns_name, v
else
elm[k.to_s] = v.to_s
end
}
else
elm.content = arg
end
end
if ns = elm.namespace_definitions.find { |n| n.prefix.nil? or n.prefix == '' }
elm.namespace = ns
end
elm
end
# Create a Text Node with +string+
def create_text_node string, &block
Nokogiri::XML::Text.new string.to_s, self, &block
end
# Create a CDATA Node containing +string+
def create_cdata string, &block
Nokogiri::XML::CDATA.new self, string.to_s, &block
end
# Create a Comment Node containing +string+
def create_comment string, &block
Nokogiri::XML::Comment.new self, string.to_s, &block
end
# The name of this document. Always returns "document"
def name
'document'
end
# A reference to +self+
def document
self
end
##
# Recursively get all namespaces from this node and its subtree and
# return them as a hash.
#
# For example, given this document:
#
# <root xmlns:foo="bar">
# <bar xmlns:hello="world" />
# </root>
#
# This method will return:
#
# { 'xmlns:foo' => 'bar', 'xmlns:hello' => 'world' }
#
# WARNING: this method will clobber duplicate names in the keys.
# For example, given this document:
#
# <root xmlns:foo="bar">
# <bar xmlns:foo="baz" />
# </root>
#
# The hash returned will look like this: { 'xmlns:foo' => 'bar' }
#
# Non-prefixed default namespaces (as in "xmlns=") are not included
# in the hash.
#
# Note that this method does an xpath lookup for nodes with
# namespaces, and as a result the order may be dependent on the
# implementation of the underlying XML library.
#
def collect_namespaces
xpath("//namespace::*").inject({}) do |hash, ns|
hash[["xmlns",ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
hash
end
end
# Get the list of decorators given +key+
def decorators key
@decorators ||= Hash.new
@decorators[key] ||= []
end
##
# Validate this Document against it's DTD. Returns a list of errors on
# the document or +nil+ when there is no DTD.
def validate
return nil unless internal_subset
internal_subset.validate self
end
##
# Explore a document with shortcut methods. See Nokogiri::Slop for details.
#
# Note that any nodes that have been instantiated before #slop!
# is called will not be decorated with sloppy behavior. So, if you're in
# irb, the preferred idiom is:
#
# irb> doc = Nokogiri::Slop my_markup
#
# and not
#
# irb> doc = Nokogiri::HTML my_markup
# ... followed by irb's implicit inspect (and therefore instantiation of every node) ...
# irb> doc.slop!
# ... which does absolutely nothing.
#
def slop!
unless decorators(XML::Node).include? Nokogiri::Decorators::Slop
decorators(XML::Node) << Nokogiri::Decorators::Slop
decorate!
end
self
end
##
# Apply any decorators to +node+
def decorate node
return unless @decorators
@decorators.each { |klass,list|
next unless node.is_a?(klass)
list.each { |moodule| node.extend(moodule) }
}
end
alias :to_xml :serialize
alias :clone :dup
# Get the hash of namespaces on the root Nokogiri::XML::Node
def namespaces
root ? root.namespaces : {}
end
##
# Create a Nokogiri::XML::DocumentFragment from +tags+
# Returns an empty fragment if +tags+ is nil.
def fragment tags = nil
DocumentFragment.new(self, tags, self.root)
end
undef_method :swap, :parent, :namespace, :default_namespace=
undef_method :add_namespace_definition, :attributes
undef_method :namespace_definitions, :line, :add_namespace
def add_child node_or_tags
raise "Document already has a root node" if root && root.name != 'nokogiri_text_wrapper'
node_or_tags = coerce(node_or_tags)
if node_or_tags.is_a?(XML::NodeSet)
raise "Document cannot have multiple root nodes" if node_or_tags.size > 1
super(node_or_tags.first)
else
super
end
end
alias :<< :add_child
##
# +JRuby+
# Wraps Java's org.w3c.dom.document and returns Nokogiri::XML::Document
def self.wrap document
raise "JRuby only method" unless Nokogiri.jruby?
return wrapJavaDocument(document)
end
##
# +JRuby+
# Returns Java's org.w3c.dom.document of this Document.
def to_java
raise "JRuby only method" unless Nokogiri.jruby?
return toJavaDocument()
end
private
def self.empty_doc? string_or_io
string_or_io.nil? ||
(string_or_io.respond_to?(:empty?) && string_or_io.empty?) ||
(string_or_io.respond_to?(:eof?) && string_or_io.eof?)
end
def implied_xpath_contexts # :nodoc:
["//"]
end
def inspect_attributes
[:name, :children]
end
end
end
end
|