Notes:
All code on this page presupposes that the following has been executed:
require 'rexml/document'
For convenience, examples on this page use
REXML::Document.new
, not REXML::Element.new
. This
is completely valid, because REXML::Document is a subclass of
REXML::Element.
The context for an element is a hash of processing directives that influence the way XML is read, stored, and written. The context entries are:
:respect_whitespace
: controls treatment of whitespace.
:compress_whitespace
: determines whether whitespace is
compressed.
:ignore_whitespace_nodes
: determines whether whitespace-only
nodes are to be ignored.
:raw
: controls treatment of special characters and entities.
The default context for a new element is {}
. You can set the
context at element-creation time:
d = REXML::Document.new('', {compress_whitespace: :all, raw: :all}) d.context # => {:compress_whitespace=>:all, :raw=>:all}
You can reset the entire context by assigning a new hash:
d.context = {ignore_whitespace_nodes: :all} d.context # => {:ignore_whitespace_nodes=>:all}
Or you can create or modify an individual entry:
d.context[:raw] = :all d.context # => {:ignore_whitespace_nodes=>:all, :raw=>:all}
:respect_whitespace
Affects: REXML::Element.new
,
REXML::Element.text=
.
By default, all parsed whitespace is respected (that is, stored whitespace not compressed):
xml_string = '<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>' d = REXML::Document.new(xml_string) d.to_s # => "<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>"
Use :respect_whitespace
with an array of element names to
specify the elements that are to have their whitespace respected;
other elements' whitespace, and whitespace between elements, will be
compressed.
In this example: foo
and baz
will have their
whitespace respected; bar
and the space between elements will
have their whitespace compressed:
d = REXML::Document.new(xml_string, {respect_whitespace: ['foo', 'baz']}) d.to_s # => "<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>" bar = d.root[2] # => <bar> ... </> bar.text = 'X Y' d.to_s # => "<root><foo>a b</foo> <bar>X Y</bar> <baz>e f</baz></root>"
:compress_whitespace
Affects: REXML::Element.new
,
REXML::Element.text=
.
Use compress_whitespace: :all
to compress whitespace both
within and between elements:
xml_string = '<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>' d = REXML::Document.new(xml_string, {compress_whitespace: :all}) d.to_s # => "<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>"
Use :compress_whitespace
with an array of element names to
compress whitespace in those elements, but not in other elements nor
between elements.
In this example, foo
and baz
will have their
whitespace compressed; bar
and the space between elements will
not:
d = REXML::Document.new(xml_string, {compress_whitespace: ['foo', 'baz']}) d.to_s # => "<root><foo>a b</foo> <bar>c d</bar> <baz>e f</baz></root>" foo = d.root[0] # => <foo> ... </> foo.text= 'X Y' d.to_s # => "<root><foo>X Y</foo> <bar>c d</bar> <baz>e f</baz></root>"
:ignore_whitespace_nodes
Affects: REXML::Element.new
.
Use ignore_whitespace_nodes: :all
to omit all whitespace-only
elements.
In this example, bar
has a text node, while nodes
foo
and baz
do not:
xml_string = '<root><foo> </foo><bar> BAR </bar><baz> </baz></root>' d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: :all}) d.to_s # => "<root><foo> FOO </foo><bar/><baz> BAZ </baz></root>" root = d.root # => <root> ... </> foo = root[0] # => <foo/> bar = root[1] # => <bar> ... </> baz = root[2] # => <baz/> foo.first.class # => NilClass bar.first.class # => REXML::Text baz.first.class # => NilClass
Use :ignore_whitespace_nodes
with an array of element names to
specify the elements that are to have whitespace nodes ignored.
In this example, bar
and baz
have text nodes,
while node foo
does not.
xml_string = '<root><foo> </foo><bar> BAR </bar><baz> </baz></root>' d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: ['foo']}) d.to_s # => "<root><foo/><bar> BAR </bar><baz> </baz></root>" root = d.root # => <root> ... </> foo = root[0] # => <foo/> bar = root[1] # => <bar> ... </> baz = root[2] # => <baz> ... </> foo.first.class # => NilClass bar.first.class # => REXML::Text baz.first.class # => REXML::Text
:raw
Affects: Element.text=
, Element.add_text
,
Text.to_s
.
Parsing of a
elements is not affected by raw
:
xml_string = '<root><a>0 < 1</a><b>1 > 0</b></root>' d = REXML::Document.new(xml_string, {:raw => ['a']}) d.root.to_s # => "<root><a>0 < 1</a><b>1 > 0</b></root>" a, b = *d.root.elements a.to_s # => "<a>0 < 1</a>" b.to_s # => "<b>1 > 0</b>"
But Element#text= is affected:
a.text = '0 < 1' b.text = '1 > 0' a.to_s # => "<a>0 < 1</a>" b.to_s # => "<b>1 &gt; 0</b>"
As is Element.add_text:
a.add_text(' so 1 > 0') b.add_text(' so 0 < 1') a.to_s # => "<a>0 < 1 so 1 > 0</a>" b.to_s # => "<b>1 &gt; 0 so 0 &lt; 1</b>"