== Element Context
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 = 'a b c d e f'
d = REXML::Document.new(xml_string)
d.to_s # => "a b c d e f"
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 # => "a b c d e f"
bar = d.root[2] # => ... >
bar.text = 'X Y'
d.to_s # => "a b X Y e f"
=== +:compress_whitespace+
Affects: +REXML::Element.new+, +REXML::Element.text=+.
Use compress_whitespace: :all
to compress whitespace both within and between elements:
xml_string = 'a b c d e f'
d = REXML::Document.new(xml_string, {compress_whitespace: :all})
d.to_s # => "a b c d e f"
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 # => "a b c d e f"
foo = d.root[0] # => ... >
foo.text= 'X Y'
d.to_s # => "X Y c d e f"
=== +: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 = ' BAR '
d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: :all})
d.to_s # => " FOO BAZ "
root = d.root # => ... >
foo = root[0] # =>
bar = root[1] # => ... >
baz = root[2] # =>
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 = ' BAR '
d = REXML::Document.new(xml_string, {ignore_whitespace_nodes: ['foo']})
d.to_s # => " BAR "
root = d.root # => ... >
foo = root[0] # =>
bar = root[1] # => ... >
baz = root[2] # => ... >
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 = '0 < 11 > 0'
d = REXML::Document.new(xml_string, {:raw => ['a']})
d.root.to_s # => "0 < 11 > 0"
a, b = *d.root.elements
a.to_s # => "0 < 1"
b.to_s # => "1 > 0"
But Element#text= is affected:
a.text = '0 < 1'
b.text = '1 > 0'
a.to_s # => "0 < 1"
b.to_s # => "1 > 0"
As is Element.add_text:
a.add_text(' so 1 > 0')
b.add_text(' so 0 < 1')
a.to_s # => "0 < 1 so 1 > 0"
b.to_s # => "1 > 0 so 0 < 1"