rexml 3.1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rexml might be problematic. Click here for more details.

Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +60 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/lib/rexml/attlistdecl.rb +63 -0
  11. data/lib/rexml/attribute.rb +192 -0
  12. data/lib/rexml/cdata.rb +68 -0
  13. data/lib/rexml/child.rb +97 -0
  14. data/lib/rexml/comment.rb +80 -0
  15. data/lib/rexml/doctype.rb +270 -0
  16. data/lib/rexml/document.rb +291 -0
  17. data/lib/rexml/dtd/attlistdecl.rb +11 -0
  18. data/lib/rexml/dtd/dtd.rb +47 -0
  19. data/lib/rexml/dtd/elementdecl.rb +18 -0
  20. data/lib/rexml/dtd/entitydecl.rb +57 -0
  21. data/lib/rexml/dtd/notationdecl.rb +40 -0
  22. data/lib/rexml/element.rb +1267 -0
  23. data/lib/rexml/encoding.rb +51 -0
  24. data/lib/rexml/entity.rb +171 -0
  25. data/lib/rexml/formatters/default.rb +112 -0
  26. data/lib/rexml/formatters/pretty.rb +142 -0
  27. data/lib/rexml/formatters/transitive.rb +58 -0
  28. data/lib/rexml/functions.rb +447 -0
  29. data/lib/rexml/instruction.rb +71 -0
  30. data/lib/rexml/light/node.rb +196 -0
  31. data/lib/rexml/namespace.rb +48 -0
  32. data/lib/rexml/node.rb +76 -0
  33. data/lib/rexml/output.rb +30 -0
  34. data/lib/rexml/parent.rb +166 -0
  35. data/lib/rexml/parseexception.rb +52 -0
  36. data/lib/rexml/parsers/baseparser.rb +586 -0
  37. data/lib/rexml/parsers/lightparser.rb +59 -0
  38. data/lib/rexml/parsers/pullparser.rb +197 -0
  39. data/lib/rexml/parsers/sax2parser.rb +273 -0
  40. data/lib/rexml/parsers/streamparser.rb +61 -0
  41. data/lib/rexml/parsers/treeparser.rb +101 -0
  42. data/lib/rexml/parsers/ultralightparser.rb +57 -0
  43. data/lib/rexml/parsers/xpathparser.rb +675 -0
  44. data/lib/rexml/quickpath.rb +266 -0
  45. data/lib/rexml/rexml.rb +32 -0
  46. data/lib/rexml/sax2listener.rb +98 -0
  47. data/lib/rexml/security.rb +28 -0
  48. data/lib/rexml/source.rb +298 -0
  49. data/lib/rexml/streamlistener.rb +93 -0
  50. data/lib/rexml/syncenumerator.rb +33 -0
  51. data/lib/rexml/text.rb +424 -0
  52. data/lib/rexml/undefinednamespaceexception.rb +9 -0
  53. data/lib/rexml/validation/relaxng.rb +539 -0
  54. data/lib/rexml/validation/validation.rb +144 -0
  55. data/lib/rexml/validation/validationexception.rb +10 -0
  56. data/lib/rexml/xmldecl.rb +116 -0
  57. data/lib/rexml/xmltokens.rb +85 -0
  58. data/lib/rexml/xpath.rb +81 -0
  59. data/lib/rexml/xpath_parser.rb +934 -0
  60. data/rexml.gemspec +42 -0
  61. metadata +131 -0
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: false
2
+ require_relative "node"
3
+
4
+ module REXML
5
+ ##
6
+ # A Child object is something contained by a parent, and this class
7
+ # contains methods to support that. Most user code will not use this
8
+ # class directly.
9
+ class Child
10
+ include Node
11
+ attr_reader :parent # The Parent of this object
12
+
13
+ # Constructor. Any inheritors of this class should call super to make
14
+ # sure this method is called.
15
+ # parent::
16
+ # if supplied, the parent of this child will be set to the
17
+ # supplied value, and self will be added to the parent
18
+ def initialize( parent = nil )
19
+ @parent = nil
20
+ # Declare @parent, but don't define it. The next line sets the
21
+ # parent.
22
+ parent.add( self ) if parent
23
+ end
24
+
25
+ # Replaces this object with another object. Basically, calls
26
+ # Parent.replace_child
27
+ #
28
+ # Returns:: self
29
+ def replace_with( child )
30
+ @parent.replace_child( self, child )
31
+ self
32
+ end
33
+
34
+ # Removes this child from the parent.
35
+ #
36
+ # Returns:: self
37
+ def remove
38
+ unless @parent.nil?
39
+ @parent.delete self
40
+ end
41
+ self
42
+ end
43
+
44
+ # Sets the parent of this child to the supplied argument.
45
+ #
46
+ # other::
47
+ # Must be a Parent object. If this object is the same object as the
48
+ # existing parent of this child, no action is taken. Otherwise, this
49
+ # child is removed from the current parent (if one exists), and is added
50
+ # to the new parent.
51
+ # Returns:: The parent added
52
+ def parent=( other )
53
+ return @parent if @parent == other
54
+ @parent.delete self if defined? @parent and @parent
55
+ @parent = other
56
+ end
57
+
58
+ alias :next_sibling :next_sibling_node
59
+ alias :previous_sibling :previous_sibling_node
60
+
61
+ # Sets the next sibling of this child. This can be used to insert a child
62
+ # after some other child.
63
+ # a = Element.new("a")
64
+ # b = a.add_element("b")
65
+ # c = Element.new("c")
66
+ # b.next_sibling = c
67
+ # # => <a><b/><c/></a>
68
+ def next_sibling=( other )
69
+ parent.insert_after self, other
70
+ end
71
+
72
+ # Sets the previous sibling of this child. This can be used to insert a
73
+ # child before some other child.
74
+ # a = Element.new("a")
75
+ # b = a.add_element("b")
76
+ # c = Element.new("c")
77
+ # b.previous_sibling = c
78
+ # # => <a><b/><c/></a>
79
+ def previous_sibling=(other)
80
+ parent.insert_before self, other
81
+ end
82
+
83
+ # Returns:: the document this child belongs to, or nil if this child
84
+ # belongs to no document
85
+ def document
86
+ return parent.document unless parent.nil?
87
+ nil
88
+ end
89
+
90
+ # This doesn't yet handle encodings
91
+ def bytes
92
+ document.encoding
93
+
94
+ to_s
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: false
2
+ require_relative "child"
3
+
4
+ module REXML
5
+ ##
6
+ # Represents an XML comment; that is, text between \<!-- ... -->
7
+ class Comment < Child
8
+ include Comparable
9
+ START = "<!--"
10
+ STOP = "-->"
11
+
12
+ # The content text
13
+
14
+ attr_accessor :string
15
+
16
+ ##
17
+ # Constructor. The first argument can be one of three types:
18
+ # @param first If String, the contents of this comment are set to the
19
+ # argument. If Comment, the argument is duplicated. If
20
+ # Source, the argument is scanned for a comment.
21
+ # @param second If the first argument is a Source, this argument
22
+ # should be nil, not supplied, or a Parent to be set as the parent
23
+ # of this object
24
+ def initialize( first, second = nil )
25
+ super(second)
26
+ if first.kind_of? String
27
+ @string = first
28
+ elsif first.kind_of? Comment
29
+ @string = first.string
30
+ end
31
+ end
32
+
33
+ def clone
34
+ Comment.new self
35
+ end
36
+
37
+ # == DEPRECATED
38
+ # See REXML::Formatters
39
+ #
40
+ # output::
41
+ # Where to write the string
42
+ # indent::
43
+ # An integer. If -1, no indenting will be used; otherwise, the
44
+ # indentation will be this number of spaces, and children will be
45
+ # indented an additional amount.
46
+ # transitive::
47
+ # Ignored by this class. The contents of comments are never modified.
48
+ # ie_hack::
49
+ # Needed for conformity to the child API, but not used by this class.
50
+ def write( output, indent=-1, transitive=false, ie_hack=false )
51
+ Kernel.warn("Comment.write is deprecated. See REXML::Formatters", uplevel: 1)
52
+ indent( output, indent )
53
+ output << START
54
+ output << @string
55
+ output << STOP
56
+ end
57
+
58
+ alias :to_s :string
59
+
60
+ ##
61
+ # Compares this Comment to another; the contents of the comment are used
62
+ # in the comparison.
63
+ def <=>(other)
64
+ other.to_s <=> @string
65
+ end
66
+
67
+ ##
68
+ # Compares this Comment to another; the contents of the comment are used
69
+ # in the comparison.
70
+ def ==( other )
71
+ other.kind_of? Comment and
72
+ (other <=> self) == 0
73
+ end
74
+
75
+ def node_type
76
+ :comment
77
+ end
78
+ end
79
+ end
80
+ #vim:ts=2 sw=2 noexpandtab:
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: false
2
+ require_relative "parent"
3
+ require_relative "parseexception"
4
+ require_relative "namespace"
5
+ require_relative 'entity'
6
+ require_relative 'attlistdecl'
7
+ require_relative 'xmltokens'
8
+
9
+ module REXML
10
+ # Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
11
+ # ... >. DOCTYPES can be used to declare the DTD of a document, as well as
12
+ # being used to declare entities used in the document.
13
+ class DocType < Parent
14
+ include XMLTokens
15
+ START = "<!DOCTYPE"
16
+ STOP = ">"
17
+ SYSTEM = "SYSTEM"
18
+ PUBLIC = "PUBLIC"
19
+ DEFAULT_ENTITIES = {
20
+ 'gt'=>EntityConst::GT,
21
+ 'lt'=>EntityConst::LT,
22
+ 'quot'=>EntityConst::QUOT,
23
+ "apos"=>EntityConst::APOS
24
+ }
25
+
26
+ # name is the name of the doctype
27
+ # external_id is the referenced DTD, if given
28
+ attr_reader :name, :external_id, :entities, :namespaces
29
+
30
+ # Constructor
31
+ #
32
+ # dt = DocType.new( 'foo', '-//I/Hate/External/IDs' )
33
+ # # <!DOCTYPE foo '-//I/Hate/External/IDs'>
34
+ # dt = DocType.new( doctype_to_clone )
35
+ # # Incomplete. Shallow clone of doctype
36
+ #
37
+ # +Note+ that the constructor:
38
+ #
39
+ # Doctype.new( Source.new( "<!DOCTYPE foo 'bar'>" ) )
40
+ #
41
+ # is _deprecated_. Do not use it. It will probably disappear.
42
+ def initialize( first, parent=nil )
43
+ @entities = DEFAULT_ENTITIES
44
+ @long_name = @uri = nil
45
+ if first.kind_of? String
46
+ super()
47
+ @name = first
48
+ @external_id = parent
49
+ elsif first.kind_of? DocType
50
+ super( parent )
51
+ @name = first.name
52
+ @external_id = first.external_id
53
+ elsif first.kind_of? Array
54
+ super( parent )
55
+ @name = first[0]
56
+ @external_id = first[1]
57
+ @long_name = first[2]
58
+ @uri = first[3]
59
+ elsif first.kind_of? Source
60
+ super( parent )
61
+ parser = Parsers::BaseParser.new( first )
62
+ event = parser.pull
63
+ if event[0] == :start_doctype
64
+ @name, @external_id, @long_name, @uri, = event[1..-1]
65
+ end
66
+ else
67
+ super()
68
+ end
69
+ end
70
+
71
+ def node_type
72
+ :doctype
73
+ end
74
+
75
+ def attributes_of element
76
+ rv = []
77
+ each do |child|
78
+ child.each do |key,val|
79
+ rv << Attribute.new(key,val)
80
+ end if child.kind_of? AttlistDecl and child.element_name == element
81
+ end
82
+ rv
83
+ end
84
+
85
+ def attribute_of element, attribute
86
+ att_decl = find do |child|
87
+ child.kind_of? AttlistDecl and
88
+ child.element_name == element and
89
+ child.include? attribute
90
+ end
91
+ return nil unless att_decl
92
+ att_decl[attribute]
93
+ end
94
+
95
+ def clone
96
+ DocType.new self
97
+ end
98
+
99
+ # output::
100
+ # Where to write the string
101
+ # indent::
102
+ # An integer. If -1, no indentation will be used; otherwise, the
103
+ # indentation will be this number of spaces, and children will be
104
+ # indented an additional amount.
105
+ # transitive::
106
+ # Ignored
107
+ # ie_hack::
108
+ # Ignored
109
+ def write( output, indent=0, transitive=false, ie_hack=false )
110
+ f = REXML::Formatters::Default.new
111
+ indent( output, indent )
112
+ output << START
113
+ output << ' '
114
+ output << @name
115
+ output << " #@external_id" if @external_id
116
+ output << " #{@long_name.inspect}" if @long_name
117
+ output << " #{@uri.inspect}" if @uri
118
+ unless @children.empty?
119
+ output << ' ['
120
+ @children.each { |child|
121
+ output << "\n"
122
+ f.write( child, output )
123
+ }
124
+ output << "\n]"
125
+ end
126
+ output << STOP
127
+ end
128
+
129
+ def context
130
+ @parent.context
131
+ end
132
+
133
+ def entity( name )
134
+ @entities[name].unnormalized if @entities[name]
135
+ end
136
+
137
+ def add child
138
+ super(child)
139
+ @entities = DEFAULT_ENTITIES.clone if @entities == DEFAULT_ENTITIES
140
+ @entities[ child.name ] = child if child.kind_of? Entity
141
+ end
142
+
143
+ # This method retrieves the public identifier identifying the document's
144
+ # DTD.
145
+ #
146
+ # Method contributed by Henrik Martensson
147
+ def public
148
+ case @external_id
149
+ when "SYSTEM"
150
+ nil
151
+ when "PUBLIC"
152
+ strip_quotes(@long_name)
153
+ end
154
+ end
155
+
156
+ # This method retrieves the system identifier identifying the document's DTD
157
+ #
158
+ # Method contributed by Henrik Martensson
159
+ def system
160
+ case @external_id
161
+ when "SYSTEM"
162
+ strip_quotes(@long_name)
163
+ when "PUBLIC"
164
+ @uri.kind_of?(String) ? strip_quotes(@uri) : nil
165
+ end
166
+ end
167
+
168
+ # This method returns a list of notations that have been declared in the
169
+ # _internal_ DTD subset. Notations in the external DTD subset are not
170
+ # listed.
171
+ #
172
+ # Method contributed by Henrik Martensson
173
+ def notations
174
+ children().select {|node| node.kind_of?(REXML::NotationDecl)}
175
+ end
176
+
177
+ # Retrieves a named notation. Only notations declared in the internal
178
+ # DTD subset can be retrieved.
179
+ #
180
+ # Method contributed by Henrik Martensson
181
+ def notation(name)
182
+ notations.find { |notation_decl|
183
+ notation_decl.name == name
184
+ }
185
+ end
186
+
187
+ private
188
+
189
+ # Method contributed by Henrik Martensson
190
+ def strip_quotes(quoted_string)
191
+ quoted_string =~ /^[\'\"].*[\'\"]$/ ?
192
+ quoted_string[1, quoted_string.length-2] :
193
+ quoted_string
194
+ end
195
+ end
196
+
197
+ # We don't really handle any of these since we're not a validating
198
+ # parser, so we can be pretty dumb about them. All we need to be able
199
+ # to do is spew them back out on a write()
200
+
201
+ # This is an abstract class. You never use this directly; it serves as a
202
+ # parent class for the specific declarations.
203
+ class Declaration < Child
204
+ def initialize src
205
+ super()
206
+ @string = src
207
+ end
208
+
209
+ def to_s
210
+ @string+'>'
211
+ end
212
+
213
+ # == DEPRECATED
214
+ # See REXML::Formatters
215
+ #
216
+ def write( output, indent )
217
+ output << to_s
218
+ end
219
+ end
220
+
221
+ public
222
+ class ElementDecl < Declaration
223
+ def initialize( src )
224
+ super
225
+ end
226
+ end
227
+
228
+ class ExternalEntity < Child
229
+ def initialize( src )
230
+ super()
231
+ @entity = src
232
+ end
233
+ def to_s
234
+ @entity
235
+ end
236
+ def write( output, indent )
237
+ output << @entity
238
+ end
239
+ end
240
+
241
+ class NotationDecl < Child
242
+ attr_accessor :public, :system
243
+ def initialize name, middle, pub, sys
244
+ super(nil)
245
+ @name = name
246
+ @middle = middle
247
+ @public = pub
248
+ @system = sys
249
+ end
250
+
251
+ def to_s
252
+ notation = "<!NOTATION #{@name} #{@middle}"
253
+ notation << " #{@public.inspect}" if @public
254
+ notation << " #{@system.inspect}" if @system
255
+ notation << ">"
256
+ notation
257
+ end
258
+
259
+ def write( output, indent=-1 )
260
+ output << to_s
261
+ end
262
+
263
+ # This method retrieves the name of the notation.
264
+ #
265
+ # Method contributed by Henrik Martensson
266
+ def name
267
+ @name
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: false
2
+ require_relative "security"
3
+ require_relative "element"
4
+ require_relative "xmldecl"
5
+ require_relative "source"
6
+ require_relative "comment"
7
+ require_relative "doctype"
8
+ require_relative "instruction"
9
+ require_relative "rexml"
10
+ require_relative "parseexception"
11
+ require_relative "output"
12
+ require_relative "parsers/baseparser"
13
+ require_relative "parsers/streamparser"
14
+ require_relative "parsers/treeparser"
15
+
16
+ module REXML
17
+ # Represents a full XML document, including PIs, a doctype, etc. A
18
+ # Document has a single child that can be accessed by root().
19
+ # Note that if you want to have an XML declaration written for a document
20
+ # you create, you must add one; REXML documents do not write a default
21
+ # declaration for you. See |DECLARATION| and |write|.
22
+ class Document < Element
23
+ # A convenient default XML declaration. If you want an XML declaration,
24
+ # the easiest way to add one is mydoc << Document::DECLARATION
25
+ # +DEPRECATED+
26
+ # Use: mydoc << XMLDecl.default
27
+ DECLARATION = XMLDecl.default
28
+
29
+ # Constructor
30
+ # @param source if supplied, must be a Document, String, or IO.
31
+ # Documents have their context and Element attributes cloned.
32
+ # Strings are expected to be valid XML documents. IOs are expected
33
+ # to be sources of valid XML documents.
34
+ # @param context if supplied, contains the context of the document;
35
+ # this should be a Hash.
36
+ def initialize( source = nil, context = {} )
37
+ @entity_expansion_count = 0
38
+ super()
39
+ @context = context
40
+ return if source.nil?
41
+ if source.kind_of? Document
42
+ @context = source.context
43
+ super source
44
+ else
45
+ build( source )
46
+ end
47
+ end
48
+
49
+ def node_type
50
+ :document
51
+ end
52
+
53
+ # Should be obvious
54
+ def clone
55
+ Document.new self
56
+ end
57
+
58
+ # According to the XML spec, a root node has no expanded name
59
+ def expanded_name
60
+ ''
61
+ #d = doc_type
62
+ #d ? d.name : "UNDEFINED"
63
+ end
64
+
65
+ alias :name :expanded_name
66
+
67
+ # We override this, because XMLDecls and DocTypes must go at the start
68
+ # of the document
69
+ def add( child )
70
+ if child.kind_of? XMLDecl
71
+ if @children[0].kind_of? XMLDecl
72
+ @children[0] = child
73
+ else
74
+ @children.unshift child
75
+ end
76
+ child.parent = self
77
+ elsif child.kind_of? DocType
78
+ # Find first Element or DocType node and insert the decl right
79
+ # before it. If there is no such node, just insert the child at the
80
+ # end. If there is a child and it is an DocType, then replace it.
81
+ insert_before_index = @children.find_index { |x|
82
+ x.kind_of?(Element) || x.kind_of?(DocType)
83
+ }
84
+ if insert_before_index # Not null = not end of list
85
+ if @children[ insert_before_index ].kind_of? DocType
86
+ @children[ insert_before_index ] = child
87
+ else
88
+ @children[ insert_before_index-1, 0 ] = child
89
+ end
90
+ else # Insert at end of list
91
+ @children << child
92
+ end
93
+ child.parent = self
94
+ else
95
+ rv = super
96
+ raise "attempted adding second root element to document" if @elements.size > 1
97
+ rv
98
+ end
99
+ end
100
+ alias :<< :add
101
+
102
+ def add_element(arg=nil, arg2=nil)
103
+ rv = super
104
+ raise "attempted adding second root element to document" if @elements.size > 1
105
+ rv
106
+ end
107
+
108
+ # @return the root Element of the document, or nil if this document
109
+ # has no children.
110
+ def root
111
+ elements[1]
112
+ #self
113
+ #@children.find { |item| item.kind_of? Element }
114
+ end
115
+
116
+ # @return the DocType child of the document, if one exists,
117
+ # and nil otherwise.
118
+ def doctype
119
+ @children.find { |item| item.kind_of? DocType }
120
+ end
121
+
122
+ # @return the XMLDecl of this document; if no XMLDecl has been
123
+ # set, the default declaration is returned.
124
+ def xml_decl
125
+ rv = @children[0]
126
+ return rv if rv.kind_of? XMLDecl
127
+ @children.unshift(XMLDecl.default)[0]
128
+ end
129
+
130
+ # @return the XMLDecl version of this document as a String.
131
+ # If no XMLDecl has been set, returns the default version.
132
+ def version
133
+ xml_decl().version
134
+ end
135
+
136
+ # @return the XMLDecl encoding of this document as an
137
+ # Encoding object.
138
+ # If no XMLDecl has been set, returns the default encoding.
139
+ def encoding
140
+ xml_decl().encoding
141
+ end
142
+
143
+ # @return the XMLDecl standalone value of this document as a String.
144
+ # If no XMLDecl has been set, returns the default setting.
145
+ def stand_alone?
146
+ xml_decl().stand_alone?
147
+ end
148
+
149
+ # :call-seq:
150
+ # doc.write(output=$stdout, indent=-1, transtive=false, ie_hack=false, encoding=nil)
151
+ # doc.write(options={:output => $stdout, :indent => -1, :transtive => false, :ie_hack => false, :encoding => nil})
152
+ #
153
+ # Write the XML tree out, optionally with indent. This writes out the
154
+ # entire XML document, including XML declarations, doctype declarations,
155
+ # and processing instructions (if any are given).
156
+ #
157
+ # A controversial point is whether Document should always write the XML
158
+ # declaration (<?xml version='1.0'?>) whether or not one is given by the
159
+ # user (or source document). REXML does not write one if one was not
160
+ # specified, because it adds unnecessary bandwidth to applications such
161
+ # as XML-RPC.
162
+ #
163
+ # Accept Nth argument style and options Hash style as argument.
164
+ # The recommended style is options Hash style for one or more
165
+ # arguments case.
166
+ #
167
+ # _Examples_
168
+ # Document.new("<a><b/></a>").write
169
+ #
170
+ # output = ""
171
+ # Document.new("<a><b/></a>").write(output)
172
+ #
173
+ # output = ""
174
+ # Document.new("<a><b/></a>").write(:output => output, :indent => 2)
175
+ #
176
+ # See also the classes in the rexml/formatters package for the proper way
177
+ # to change the default formatting of XML output.
178
+ #
179
+ # _Examples_
180
+ #
181
+ # output = ""
182
+ # tr = Transitive.new
183
+ # tr.write(Document.new("<a><b/></a>"), output)
184
+ #
185
+ # output::
186
+ # output an object which supports '<< string'; this is where the
187
+ # document will be written.
188
+ # indent::
189
+ # An integer. If -1, no indenting will be used; otherwise, the
190
+ # indentation will be twice this number of spaces, and children will be
191
+ # indented an additional amount. For a value of 3, every item will be
192
+ # indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
193
+ # transitive::
194
+ # If transitive is true and indent is >= 0, then the output will be
195
+ # pretty-printed in such a way that the added whitespace does not affect
196
+ # the absolute *value* of the document -- that is, it leaves the value
197
+ # and number of Text nodes in the document unchanged.
198
+ # ie_hack::
199
+ # This hack inserts a space before the /> on empty tags to address
200
+ # a limitation of Internet Explorer. Defaults to false
201
+ # encoding::
202
+ # Encoding name as String. Change output encoding to specified encoding
203
+ # instead of encoding in XML declaration.
204
+ # Defaults to nil. It means encoding in XML declaration is used.
205
+ def write(*arguments)
206
+ if arguments.size == 1 and arguments[0].class == Hash
207
+ options = arguments[0]
208
+
209
+ output = options[:output]
210
+ indent = options[:indent]
211
+ transitive = options[:transitive]
212
+ ie_hack = options[:ie_hack]
213
+ encoding = options[:encoding]
214
+ else
215
+ output, indent, transitive, ie_hack, encoding, = *arguments
216
+ end
217
+
218
+ output ||= $stdout
219
+ indent ||= -1
220
+ transitive = false if transitive.nil?
221
+ ie_hack = false if ie_hack.nil?
222
+ encoding ||= xml_decl.encoding
223
+
224
+ if encoding != 'UTF-8' && !output.kind_of?(Output)
225
+ output = Output.new( output, encoding )
226
+ end
227
+ formatter = if indent > -1
228
+ if transitive
229
+ require_relative "formatters/transitive"
230
+ REXML::Formatters::Transitive.new( indent, ie_hack )
231
+ else
232
+ REXML::Formatters::Pretty.new( indent, ie_hack )
233
+ end
234
+ else
235
+ REXML::Formatters::Default.new( ie_hack )
236
+ end
237
+ formatter.write( self, output )
238
+ end
239
+
240
+
241
+ def Document::parse_stream( source, listener )
242
+ Parsers::StreamParser.new( source, listener ).parse
243
+ end
244
+
245
+ # Set the entity expansion limit. By default the limit is set to 10000.
246
+ #
247
+ # Deprecated. Use REXML::Security.entity_expansion_limit= instead.
248
+ def Document::entity_expansion_limit=( val )
249
+ Security.entity_expansion_limit = val
250
+ end
251
+
252
+ # Get the entity expansion limit. By default the limit is set to 10000.
253
+ #
254
+ # Deprecated. Use REXML::Security.entity_expansion_limit= instead.
255
+ def Document::entity_expansion_limit
256
+ return Security.entity_expansion_limit
257
+ end
258
+
259
+ # Set the entity expansion limit. By default the limit is set to 10240.
260
+ #
261
+ # Deprecated. Use REXML::Security.entity_expansion_text_limit= instead.
262
+ def Document::entity_expansion_text_limit=( val )
263
+ Security.entity_expansion_text_limit = val
264
+ end
265
+
266
+ # Get the entity expansion limit. By default the limit is set to 10240.
267
+ #
268
+ # Deprecated. Use REXML::Security.entity_expansion_text_limit instead.
269
+ def Document::entity_expansion_text_limit
270
+ return Security.entity_expansion_text_limit
271
+ end
272
+
273
+ attr_reader :entity_expansion_count
274
+
275
+ def record_entity_expansion
276
+ @entity_expansion_count += 1
277
+ if @entity_expansion_count > Security.entity_expansion_limit
278
+ raise "number of entity expansions exceeded, processing aborted."
279
+ end
280
+ end
281
+
282
+ def document
283
+ self
284
+ end
285
+
286
+ private
287
+ def build( source )
288
+ Parsers::TreeParser.new( source, self ).parse
289
+ end
290
+ end
291
+ end