Class: REXML::Document
- Defined in:
- lib/rexml/document.rb
Overview
Represents an XML document.
A document may have:
-
A single child that may be accessed via method #root.
-
An XML declaration.
-
A document type.
-
Processing instructions.
In a Hurry?
If you’re somewhat familiar with XML and have a particular task in mind, you may want to see the tasks pages, and in particular, the tasks page for documents.
Constant Summary collapse
Constants inherited from Element
Constants included from Namespace
Namespace::NAMESPLIT, Namespace::NAME_WITHOUT_NAMESPACE
Constants included from XMLTokens
XMLTokens::NAME, XMLTokens::NAMECHAR, XMLTokens::NAME_CHAR, XMLTokens::NAME_START_CHAR, XMLTokens::NAME_STR, XMLTokens::NCNAME_STR, XMLTokens::NMTOKEN, XMLTokens::NMTOKENS, XMLTokens::REFERENCE
Instance Attribute Summary collapse
-
#entity_expansion_count ⇒ Object
readonly
Returns the value of attribute entity_expansion_count.
-
#entity_expansion_limit ⇒ Object
writeonly
Sets the attribute entity_expansion_limit.
-
#entity_expansion_text_limit ⇒ Object
Returns the value of attribute entity_expansion_text_limit.
Attributes inherited from Element
#attributes, #context, #elements
Attributes included from Namespace
Attributes inherited from Child
Class Method Summary collapse
-
.entity_expansion_limit ⇒ Object
Get the entity expansion limit.
-
.entity_expansion_limit=(val) ⇒ Object
Set the entity expansion limit.
-
.entity_expansion_text_limit ⇒ Object
Get the entity expansion limit.
-
.entity_expansion_text_limit=(val) ⇒ Object
Set the entity expansion limit.
- .parse_stream(source, listener) ⇒ Object
Instance Method Summary collapse
-
#add(child) ⇒ Object
(also: #<<)
:call-seq: add(xml_decl) -> self add(doc_type) -> self add(object) -> self.
-
#add_element(arg = nil, arg2 = nil) ⇒ Object
:call-seq: add_element(name_or_element = nil, attributes = nil) -> new_element.
-
#clone ⇒ Object
:call-seq: clone -> new_document.
-
#doctype ⇒ Object
:call-seq: doctype -> doc_type or nil.
- #document ⇒ Object
-
#encoding ⇒ Object
:call-seq: encoding -> encoding_string.
-
#expanded_name ⇒ Object
(also: #name)
:call-seq: expanded_name -> empty_string.
-
#initialize(source = nil, context = {}) ⇒ Document
constructor
:call-seq: new(string = nil, context = {}) -> new_document new(io_stream = nil, context = {}) -> new_document new(document = nil, context = {}) -> new_document.
-
#node_type ⇒ Object
:call-seq: node_type -> :document.
- #record_entity_expansion ⇒ Object
-
#root ⇒ Object
:call-seq: root -> root_element or nil.
-
#stand_alone? ⇒ Boolean
:call-seq: stand_alone?.
-
#version ⇒ Object
:call-seq: version -> version_string.
-
#write(*arguments) ⇒ Object
:call-seq: doc.write(output=$stdout, indent=-1, transtive=false, ie_hack=false, encoding=nil) doc.write(options==> $stdout, :indent => -1, :transtive => false, :ie_hack => false, :encoding => nil).
-
#xml_decl ⇒ Object
:call-seq: xml_decl -> xml_decl.
Methods inherited from Element
#[], #add_attribute, #add_attributes, #add_namespace, #add_text, #attribute, #cdatas, #comments, #delete_attribute, #delete_element, #delete_namespace, #each_element, #each_element_with_attribute, #each_element_with_text, #get_elements, #get_text, #has_attributes?, #has_elements?, #has_text?, #ignore_whitespace_nodes, #inspect, #instructions, #namespace, #namespaces, #next_element, #prefixes, #previous_element, #raw, #root_node, #text, #text=, #texts, #whitespace, #xpath
Methods included from Namespace
#fully_expanded_name, #has_name?
Methods inherited from Parent
#[], #[]=, #deep_clone, #delete, #delete_at, #delete_if, #each, #each_index, #index, #insert_after, #insert_before, #parent?, #replace_child, #size, #to_a, #unshift
Methods inherited from Child
#bytes, #next_sibling=, #previous_sibling=, #remove, #replace_with
Methods included from Node
#each_recursive, #find_first_recursive, #indent, #index_in_parent, #next_sibling_node, #parent?, #previous_sibling_node, #to_s
Constructor Details
#initialize(source = nil, context = {}) ⇒ Document
:call-seq:
new(string = nil, context = {}) -> new_document
new(io_stream = nil, context = {}) -> new_document
new(document = nil, context = {}) -> new_document
Returns a new REXML::Document object.
When no arguments are given, returns an empty document:
d = REXML::Document.new
d.to_s # => ""
When argument string
is given, it must be a string containing a valid XML document:
xml_string = '<root><foo>Foo</foo><bar>Bar</bar></root>'
d = REXML::Document.new(xml_string)
d.to_s # => "<root><foo>Foo</foo><bar>Bar</bar></root>"
When argument io_stream
is given, it must be an IO object that is opened for reading, and when read must return a valid XML document:
File.write('t.xml', xml_string)
d = File.open('t.xml', 'r') do |io|
REXML::Document.new(io)
end
d.to_s # => "<root><foo>Foo</foo><bar>Bar</bar></root>"
When argument document
is given, it must be an existing document object, whose context and attributes (but not children) are cloned into the new document:
d = REXML::Document.new(xml_string)
d.children # => [<root> ... </>]
d.context = {raw: :all, compress_whitespace: :all}
d.add_attributes({'bar' => 0, 'baz' => 1})
d1 = REXML::Document.new(d)
d1.children # => []
d1.context # => {:raw=>:all, :compress_whitespace=>:all}
d1.attributes # => {"bar"=>bar='0', "baz"=>baz='1'}
When argument context
is given, it must be a hash containing context entries for the document; see Element Context:
context = {raw: :all, compress_whitespace: :all}
d = REXML::Document.new(xml_string, context)
d.context # => {:raw=>:all, :compress_whitespace=>:all}
92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/rexml/document.rb', line 92 def initialize( source = nil, context = {} ) @entity_expansion_count = 0 @entity_expansion_limit = Security.entity_expansion_limit @entity_expansion_text_limit = Security.entity_expansion_text_limit super() @context = context return if source.nil? if source.kind_of? Document @context = source.context super source else build( source ) end end |
Instance Attribute Details
#entity_expansion_count ⇒ Object (readonly)
Returns the value of attribute entity_expansion_count.
435 436 437 |
# File 'lib/rexml/document.rb', line 435 def entity_expansion_count @entity_expansion_count end |
#entity_expansion_limit=(value) ⇒ Object (writeonly)
Sets the attribute entity_expansion_limit
436 437 438 |
# File 'lib/rexml/document.rb', line 436 def entity_expansion_limit=(value) @entity_expansion_limit = value end |
#entity_expansion_text_limit ⇒ Object
Returns the value of attribute entity_expansion_text_limit.
437 438 439 |
# File 'lib/rexml/document.rb', line 437 def entity_expansion_text_limit @entity_expansion_text_limit end |
Class Method Details
.entity_expansion_limit ⇒ Object
Get the entity expansion limit. By default the limit is set to 10000.
Deprecated. Use REXML::Security.entity_expansion_limit= instead.
417 418 419 |
# File 'lib/rexml/document.rb', line 417 def Document::entity_expansion_limit return Security.entity_expansion_limit end |
.entity_expansion_limit=(val) ⇒ Object
Set the entity expansion limit. By default the limit is set to 10000.
Deprecated. Use REXML::Security.entity_expansion_limit= instead.
410 411 412 |
# File 'lib/rexml/document.rb', line 410 def Document::entity_expansion_limit=( val ) Security.entity_expansion_limit = val end |
.entity_expansion_text_limit ⇒ Object
Get the entity expansion limit. By default the limit is set to 10240.
Deprecated. Use REXML::Security.entity_expansion_text_limit instead.
431 432 433 |
# File 'lib/rexml/document.rb', line 431 def Document::entity_expansion_text_limit return Security.entity_expansion_text_limit end |
.entity_expansion_text_limit=(val) ⇒ Object
Set the entity expansion limit. By default the limit is set to 10240.
Deprecated. Use REXML::Security.entity_expansion_text_limit= instead.
424 425 426 |
# File 'lib/rexml/document.rb', line 424 def Document::entity_expansion_text_limit=( val ) Security.entity_expansion_text_limit = val end |
.parse_stream(source, listener) ⇒ Object
403 404 405 |
# File 'lib/rexml/document.rb', line 403 def Document::parse_stream( source, listener ) Parsers::StreamParser.new( source, listener ).parse end |
Instance Method Details
#add(child) ⇒ Object Also known as: <<
:call-seq:
add(xml_decl) -> self
add(doc_type) -> self
add(object) -> self
Adds an object to the document; returns self
.
When argument xml_decl
is given, it must be an REXML::XMLDecl object, which becomes the XML declaration for the document, replacing the previous XML declaration if any:
d = REXML::Document.new
d.xml_decl.to_s # => ""
d.add(REXML::XMLDecl.new('2.0'))
d.xml_decl.to_s # => "<?xml version='2.0'?>"
When argument doc_type
is given, it must be an REXML::DocType object, which becomes the document type for the document, replacing the previous document type, if any:
d = REXML::Document.new
d.doctype.to_s # => ""
d.add(REXML::DocType.new('foo'))
d.doctype.to_s # => "<!DOCTYPE foo>"
When argument object
(not an REXML::XMLDecl or REXML::DocType object) is given it is added as the last child:
d = REXML::Document.new
d.add(REXML::Element.new('foo'))
d.to_s # => "<foo/>"
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 |
# File 'lib/rexml/document.rb', line 172 def add( child ) if child.kind_of? XMLDecl if @children[0].kind_of? XMLDecl @children[0] = child else @children.unshift child end child.parent = self elsif child.kind_of? DocType # Find first Element or DocType node and insert the decl right # before it. If there is no such node, just insert the child at the # end. If there is a child and it is an DocType, then replace it. insert_before_index = @children.find_index { |x| x.kind_of?(Element) || x.kind_of?(DocType) } if insert_before_index # Not null = not end of list if @children[ insert_before_index ].kind_of? DocType @children[ insert_before_index ] = child else @children[ insert_before_index-1, 0 ] = child end else # Insert at end of list @children << child end child.parent = self else rv = super raise "attempted adding second root element to document" if @elements.size > 1 rv end end |
#add_element(arg = nil, arg2 = nil) ⇒ Object
:call-seq:
add_element(name_or_element = nil, attributes = nil) -> new_element
Adds an element to the document by calling REXML::Element.add_element:
REXML::Element.add_element(name_or_element, attributes)
211 212 213 214 215 |
# File 'lib/rexml/document.rb', line 211 def add_element(arg=nil, arg2=nil) rv = super raise "attempted adding second root element to document" if @elements.size > 1 rv end |
#clone ⇒ Object
:call-seq:
clone -> new_document
Returns the new document resulting from executing Document.new(self)
. See Document.new.
122 123 124 |
# File 'lib/rexml/document.rb', line 122 def clone Document.new self end |
#doctype ⇒ Object
243 244 245 |
# File 'lib/rexml/document.rb', line 243 def doctype @children.find { |item| item.kind_of? DocType } end |
#document ⇒ Object
446 447 448 |
# File 'lib/rexml/document.rb', line 446 def document self end |
#encoding ⇒ Object
292 293 294 |
# File 'lib/rexml/document.rb', line 292 def encoding xml_decl().encoding end |
#expanded_name ⇒ Object Also known as: name
:call-seq:
expanded_name -> empty_string
Returns an empty string.
131 132 133 134 135 |
# File 'lib/rexml/document.rb', line 131 def '' #d = doc_type #d ? d.name : "UNDEFINED" end |
#node_type ⇒ Object
:call-seq:
node_type -> :document
Returns the symbol :document
.
112 113 114 |
# File 'lib/rexml/document.rb', line 112 def node_type :document end |
#record_entity_expansion ⇒ Object
439 440 441 442 443 444 |
# File 'lib/rexml/document.rb', line 439 def record_entity_expansion @entity_expansion_count += 1 if @entity_expansion_count > @entity_expansion_limit raise "number of entity expansions exceeded, processing aborted." end end |
#root ⇒ Object
227 228 229 230 231 |
# File 'lib/rexml/document.rb', line 227 def root elements[1] #self #@children.find { |item| item.kind_of? Element } end |
#stand_alone? ⇒ Boolean
307 308 309 |
# File 'lib/rexml/document.rb', line 307 def stand_alone? xml_decl().stand_alone? end |
#version ⇒ Object
277 278 279 |
# File 'lib/rexml/document.rb', line 277 def version xml_decl().version end |
#write(*arguments) ⇒ Object
:call-seq:
doc.write(output=$stdout, indent=-1, transtive=false, ie_hack=false, encoding=nil)
doc.write(={:output => $stdout, :indent => -1, :transtive => false, :ie_hack => false, :encoding => nil})
Write the XML tree out, optionally with indent. This writes out the entire XML document, including XML declarations, doctype declarations, and processing instructions (if any are given).
A controversial point is whether Document should always write the XML declaration (<?xml version=‘1.0’?>) whether or not one is given by the user (or source document). REXML does not write one if one was not specified, because it adds unnecessary bandwidth to applications such as XML-RPC.
Accept Nth argument style and options Hash style as argument. The recommended style is options Hash style for one or more arguments case.
Examples
Document.new("<a><b/></a>").write
output = ""
Document.new("<a><b/></a>").write(output)
output = ""
Document.new("<a><b/></a>").write(:output => output, :indent => 2)
See also the classes in the rexml/formatters package for the proper way to change the default formatting of XML output.
Examples
output = ""
tr = Transitive.new
tr.write(Document.new("<a><b/></a>"), output)
- output
-
output an object which supports ‘<< string’; this is where the document will be written.
- indent
-
An integer. If -1, no indenting will be used; otherwise, the indentation will be twice this number of spaces, and children will be indented an additional amount. For a value of 3, every item will be indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
- transitive
-
If transitive is true and indent is >= 0, then the output will be pretty-printed in such a way that the added whitespace does not affect the absolute value of the document – that is, it leaves the value and number of Text nodes in the document unchanged.
- ie_hack
-
This hack inserts a space before the /> on empty tags to address a limitation of Internet Explorer. Defaults to false
- encoding
-
Encoding name as String. Change output encoding to specified encoding instead of encoding in XML declaration. Defaults to nil. It means encoding in XML declaration is used.
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/rexml/document.rb', line 367 def write(*arguments) if arguments.size == 1 and arguments[0].class == Hash = arguments[0] output = [:output] indent = [:indent] transitive = [:transitive] ie_hack = [:ie_hack] encoding = [:encoding] else output, indent, transitive, ie_hack, encoding, = *arguments end output ||= $stdout indent ||= -1 transitive = false if transitive.nil? ie_hack = false if ie_hack.nil? encoding ||= xml_decl.encoding if encoding != 'UTF-8' && !output.kind_of?(Output) output = Output.new( output, encoding ) end formatter = if indent > -1 if transitive require_relative "formatters/transitive" REXML::Formatters::Transitive.new( indent, ie_hack ) else REXML::Formatters::Pretty.new( indent, ie_hack ) end else REXML::Formatters::Default.new( ie_hack ) end formatter.write( self, output ) end |
#xml_decl ⇒ Object
:call-seq:
xml_decl -> xml_decl
Returns the XMLDecl object for the document, if it exists, otherwise the default XMLDecl object:
d = REXML::Document.new('<?xml version="1.0" encoding="UTF-8"?>')
d.xml_decl.class # => REXML::XMLDecl
d.xml_decl.to_s # => "<?xml version='1.0' encoding='UTF-8'?>"
d = REXML::Document.new('')
d.xml_decl.class # => REXML::XMLDecl
d.xml_decl.to_s # => ""
260 261 262 263 264 |
# File 'lib/rexml/document.rb', line 260 def xml_decl rv = @children[0] return rv if rv.kind_of? XMLDecl @children.unshift(XMLDecl.default)[0] end |