summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rexml-3.4.1/doc/rexml/context.rdoc
blob: 7ef01f7b4ad9dec0d196a0f4bf495c582c19bf9e (plain)
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
== 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 <tt>{}</tt>.
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 <tt>compress_whitespace: :all</tt>
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 <tt>ignore_whitespace_nodes: :all</tt> 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 &lt; 1</a><b>1 &gt; 0</b></root>'
  d = REXML::Document.new(xml_string, {:raw => ['a']})
  d.root.to_s # => "<root><a>0 &lt; 1</a><b>1 &gt; 0</b></root>"
  a, b = *d.root.elements
  a.to_s # => "<a>0 &lt; 1</a>"
  b.to_s # => "<b>1 &gt; 0</b>"

But Element#text= is affected:

  a.text = '0 &lt; 1'
  b.text = '1 &gt; 0'
  a.to_s # => "<a>0 &lt; 1</a>"
  b.to_s # => "<b>1 &amp;gt; 0</b>"

As is Element.add_text:

  a.add_text(' so 1 &gt; 0')
  b.add_text(' so 0 &lt; 1')
  a.to_s # => "<a>0 &lt; 1 so 1 &gt; 0</a>"
  b.to_s # => "<b>1 &amp;gt; 0 so 0 &amp;lt; 1</b>"