123456789_123456789_123456789_123456789_123456789_

Class: REXML::Document

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Element, Parent, Child
Instance Chain:
self, Element, Namespace, XMLTokens, Parent, Enumerable, Child, Node
Inherits: REXML::Element
Defined in: lib/rexml/document.rb

Overview

Represents a full XML document, including PIs, a doctype, etc. A Document has a single child that can be accessed by root(). Note that if you want to have an XML declaration written for a document you create, you must add one; ::REXML documents do not write a default declaration for you. See |DECLARATION| and |write|.

Constant Summary

XMLTokens - Included

NAME, NAMECHAR, NAME_CHAR, NAME_START_CHAR, NAME_STR, NCNAME_STR, NMTOKEN, NMTOKENS, REFERENCE

Namespace - Included

NAMESPLIT

Element - Inherited

UNDEFINED

Class Attribute Summary

Class Method Summary

Element - Inherited

.new
Constructor arg

Parent - Inherited

.new

Constructor.

Child - Inherited

.new

Constructor.

Instance Attribute Summary

Element - Inherited

#context

The context holds information about the processing environment, such as whitespace handling.

#attributes

Mechanisms for accessing attributes and child elements of this element.

#elements

Mechanisms for accessing attributes and child elements of this element.

#has_attributes?

Evaluates to true if this element has any attributes set, false otherwise.

#has_elements?

Evaluates to true if this element has at least one child Element doc = Document.new “<a><b/><c>Text</c></a>” doc.root.has_elements # -> true doc.elements.has_elements # -> false doc.elements.has_elements # -> false.

#has_text?

Evaluates to true if this element has at least one Text child.

Namespace - Included

#name

The name of the object, valid if set.

#name=

Sets the name and the expanded name.

#prefix

The expanded name of the object, valid if name is set.

#expanded_name

The name of the object, valid if set.

#local_name

Alias for Namespace#name.

Parent - Inherited

Child - Inherited

#next_sibling
#next_sibling=

Sets the next sibling of this child.

#parent

The Parent of this object.

#parent=

Sets the parent of this child to the supplied argument.

#previous_sibling
#previous_sibling=

Sets the previous sibling of this child.

Node - Included

Instance Method Summary

Element - Inherited

#[]

Fetches an attribute value or a child.

#add_attribute

Adds an attribute to this element, overwriting any existing attribute by the same name.

#add_attributes

Add multiple attributes to this element.

#add_element

Adds a child to this element, optionally setting attributes in the element.

#add_namespace

Adds a namespace to this element.

#add_text

A helper method to add a Text child.

#attribute,
#cdatas

Get an array of all CData children.

#clone

Creates a shallow copy of self.

#comments

Get an array of all Comment children.

#delete_attribute
Removes an attribute key
#delete_element

Deletes a child element.

#delete_namespace

Removes a namespace from this node.

#document

Evaluates to the document to which this element belongs, or nil if this element doesn't belong to a document.

#each_element

Synonym for Element#elements.each.

#each_element_with_attribute

Iterates through the child elements, yielding for each Element that has a particular attribute set.

#each_element_with_text

Iterates through the children, yielding for each Element that has a particular text set.

#get_elements

Synonym for Element.to_a This is a little slower than calling elements.each directly.

#get_text

Returns the first child Text node, if any, or nil otherwise.

#ignore_whitespace_nodes, #inspect,
#instructions

Get an array of all Instruction children.

#namespace

Evaluates to the URI for a prefix, or the empty string if no such namespace is declared for this element.

#namespaces,
#next_element

Returns the next sibling that is an element, or nil if there is no Element sibling after this one doc = Document.new '<a><b/>text<c/></a>' doc.root.elements.next_element #-> <c/> doc.root.elements.next_element #-> nil.

#node_type,
#prefixes

Evaluates to an ::Array containing the prefixes (names) of all defined namespaces at this context node.

#previous_element

Returns the previous sibling that is an element, or nil if there is no Element sibling prior to this one doc = Document.new '<a><b/>text<c/></a>' doc.root.elements.previous_element #-> <b/> doc.root.elements.previous_element #-> nil.

#raw

Evaluates to true if raw mode is set for this element.

#root,
#root_node

Evaluates to the root node of the document that this element belongs to.

#text

A convenience method which returns the String value of the first child text element, if one exists, and nil otherwise.

#text=

Sets the first Text child of this object.

#texts

Get an array of all Text children.

#whitespace

Evaluates to true if whitespace is respected for this element.

#write

DEPRECATED See Formatters

#xpath, #__to_xpath_helper,
#each_with_something

A private helper method.

Namespace - Included

#fully_expanded_name

Fully expand the name, even if the prefix wasn't specified in the source file.

#has_name?

Compares names optionally WITH namespaces.

Parent - Inherited

#<<

Alias for Parent#push.

#[]

Fetches a child at a given index.

#[]=

Set an index entry.

#add,
#children

Alias for Parent#to_a.

#deep_clone

Deeply clones this object.

#delete, #delete_at, #delete_if, #each,
#each_child

Alias for Parent#each.

#each_index,
#index

Fetches the index of a given child of this parent.

#insert_after

Inserts an child after another child child2 will be inserted after child1 in the child list of the parent.

#insert_before

Inserts an child before another child child2 will be inserted before child1 in the child list of the parent.

#length

Alias for Parent#size.

#push

Alias for Parent#add.

#replace_child

Replaces one child with another, making sure the nodelist is correct Child).

#size, #to_a, #unshift

Child - Inherited

#bytes

This doesn't yet handle encodings.

#document
Returns

the document this child belongs to, or nil if this child belongs to no document.

#remove

Removes this child from the parent.

#replace_with

Replaces this object with another object.

Node - Included

#each_recursive

Visit all subnodes of self recursively.

#find_first_recursive

Find (and return) first subnode (recursively) for which the block evaluates to true.

#indent,
#index_in_parent

Returns the position that self holds in its parent's array, indexed from 1.

#next_sibling_node, #previous_sibling_node,
#to_s
indent

Constructor Details

.new(source = nil, context = {}) ⇒ Document

Constructor Documents have their context and Element attributes cloned. Strings are expected to be valid XML documents. IOs are expected to be sources of valid XML documents. this should be a Hash.

Parameters:

  • source (defaults to: nil)

    if supplied, must be a Document, String, or IO.

  • context (defaults to: {})

    if supplied, contains the context of the document;

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 36

def initialize( source = nil, context = {} )
  @entity_expansion_count = 0
  super()
  @context = context
  return if source.nil?
  if source.kind_of? Document
    @context = source.context
    super source
  else
    build(  source )
  end
end

Class Attribute Details

.entity_expansion_limit (rw)

Get the entity expansion limit. By default the limit is set to 10000.

Deprecated. Use Security.entity_expansion_limit= instead.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 255

def Document::entity_expansion_limit
  return Security.entity_expansion_limit
end

.entity_expansion_limit=(val) (rw)

Set the entity expansion limit. By default the limit is set to 10000.

Deprecated. Use Security.entity_expansion_limit= instead.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 248

def Document::entity_expansion_limit=( val )
  Security.entity_expansion_limit = val
end

.entity_expansion_text_limit (rw)

Get the entity expansion limit. By default the limit is set to 10240.

Deprecated. Use Security.entity_expansion_text_limit instead.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 269

def Document::entity_expansion_text_limit
  return Security.entity_expansion_text_limit
end

.entity_expansion_text_limit=(val) (rw)

Set the entity expansion limit. By default the limit is set to 10240.

Deprecated. Use Security.entity_expansion_text_limit= instead.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 262

def Document::entity_expansion_text_limit=( val )
  Security.entity_expansion_text_limit = val
end

Class Method Details

.parse_stream(source, listener)

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 241

def Document::parse_stream( source, listener )
  Parsers::StreamParser.new( source, listener ).parse
end

Instance Attribute Details

#entity_expansion_count (readonly)

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 273

attr_reader :entity_expansion_count

#stand_alone?Boolean (readonly)

If no XMLDecl has been set, returns the default setting.

Returns:

  • (Boolean)

    the XMLDecl standalone value of this document as a String.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 145

def stand_alone?
  xml_decl().stand_alone?
end

Instance Method Details

#<<(child)

Alias for #add.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 100

alias :<< :add

#add(child) Also known as: #<<

We override this, because XMLDecls and DocTypes must go at the start of the document

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 69

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)

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 102

def add_element(arg=nil, arg2=nil)
  rv = super
  raise "attempted adding second root element to document" if @elements.size > 1
  rv
end

#build(source) (private)

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 287

def build( source )
  Parsers::TreeParser.new( source, self ).parse
end

#clone

Should be obvious

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 54

def clone
  Document.new self
end

#doctypeObject

and nil otherwise.

Returns:

  • the DocType child of the document, if one exists,

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 118

def doctype
  @children.find { |item| item.kind_of? DocType }
end

#document

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 282

def document
  self
end

#encodingObject

Encoding object. If no XMLDecl has been set, returns the default encoding.

Returns:

  • the XMLDecl encoding of this document as an

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 139

def encoding
  xml_decl().encoding
end

#expanded_name Also known as: #name

According to the XML spec, a root node has no expanded name

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 59

def expanded_name
  ''
  #d = doc_type
  #d ? d.name : "UNDEFINED"
end

#name

Alias for #expanded_name.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 65

alias :name :expanded_name

#node_type

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 49

def node_type
  :document
end

#record_entity_expansion

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 275

def record_entity_expansion
  @entity_expansion_count += 1
  if @entity_expansion_count > Security.entity_expansion_limit
    raise "number of entity expansions exceeded, processing aborted."
  end
end

#rootObject

has no children.

Returns:

  • the root Element of the document, or nil if this document

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 110

def root
  elements[1]
  #self
  #@children.find { |item| item.kind_of? Element }
end

#versionObject

If no XMLDecl has been set, returns the default version.

Returns:

  • the XMLDecl version of this document as a String.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 132

def version
  xml_decl().version
end

#write(output = $stdout, indent = -1, transtive = false, ie_hack = false, encoding = nil) #write(options={:output) ⇒ $stdout, :indent

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.

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 205

def write(*arguments)
  if arguments.size == 1 and arguments[0].class == Hash
    options = arguments[0]

    output     = options[:output]
    indent     = options[:indent]
    transitive = options[:transitive]
    ie_hack    = options[:ie_hack]
    encoding   = options[: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 "rexml/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_declObject

set, the default declaration is returned.

Returns:

[ GitHub ]

  
# File 'lib/rexml/document.rb', line 124

def xml_decl
  rv = @children[0]
  return rv if rv.kind_of? XMLDecl
  @children.unshift(XMLDecl.default)[0]
end