Class: XML::DOM::Builder

Inherits:
Parser
  • Object
show all
Includes:
XML::DOM
Defined in:
lib/xml/dom/builder.rb

Overview

Class XML::DOM::Builder (XML::SimpleTreeBuilder)

superclass

XML::Parser

Constant Summary

Constants included from XML::DOM

Attribute

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from XML::DOM

tou16

Instance Attribute Details

#createCDATASectionObject

Returns the value of attribute createCDATASection.



27
28
29
# File 'lib/xml/dom/builder.rb', line 27

def createCDATASection
  @createCDATASection
end

#createEntityReferenceObject

Returns the value of attribute createEntityReference.



28
29
30
# File 'lib/xml/dom/builder.rb', line 28

def createEntityReference
  @createEntityReference
end

Class Method Details

.new(level = 0, *args) ⇒ Object

Class Methods

--- DOM::Builder.new(level = 0, *args)

Constructor of DOM builder.

usage: parser = XML::SimpleTreeBuilder.new(level)

level: 0 -- ignore default events (defualt)
       1 -- catch default events and create the Comment,
            the EntityReference, the XML declaration (as PI) and
            the non-DOM-compliant DocumentType nodes.


55
56
57
58
59
60
61
62
# File 'lib/xml/dom/builder.rb', line 55

def self.new(level = 0, *args)
  document = Document.new
  ret = super(*args)
  external = false
  external = true if args[0].is_a?(SimpleTreeBuilder)
  ret.__initialize__(level, document, external)
  ret
end

Instance Method Details

#__initialize__(level, document, external) ⇒ Object

Constructor

parser = XML::SimpleTreeBuilder.new(level)
  level: 0 -- ignore default events (defualt)
         1 -- catch default events and create the Comment,
              the EntityReference, the XML declaration (as PI) and
              the non-DOM-compliant DocumentType nodes.


70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/xml/dom/builder.rb', line 70

def __initialize__(level, document, external)
  @tree = nil
  @level = level
  @document = document
  @external = external
  @createCDATASection = false
  @createEntityReference = false
  if @level > 0
    @createCDATASection = true
    @createEntityReference = true
    def self.default(data); defaultHandler(data); end
  end
end

#cdataConverter(str) ⇒ Object

User redefinable cdata encoding converter



104
105
106
# File 'lib/xml/dom/builder.rb', line 104

def cdataConverter(str)
  str
end

#character(data) ⇒ Object



167
168
169
# File 'lib/xml/dom/builder.rb', line 167

def character(data)
 @cdata_buf << data
end

#comment(data) ⇒ Object



221
222
223
224
225
226
# File 'lib/xml/dom/builder.rb', line 221

def comment(data)
  text
  comment = @document.createComment(cdataConverter(data))
  ## Comment should not be converted
  @current.appendChild(comment)
end

#defaultHandler(data) ⇒ Object



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/xml/dom/builder.rb', line 228

def defaultHandler(data)
  if data =~ /^\&(.+);$/
    eref = @document.createEntityReference(nameConverter($1))
    @current.appendChild(eref)
  elsif data =~ /^<\?xml\s*([\s\S]*)\?>$/
    ## XML declaration should not be a PI.
    pi = @document.createProcessingInstruction("xml",
                                   cdataConverter($1))
    @current.appendChild(pi)
  elsif @inDocDecl == 0 && data =~ /^<\!DOCTYPE$/
    @inDocDecl = 1
    @inDecl = 0
    @idRest = 0
    @extID = nil
  elsif @inDocDecl == 1
    if data == "["
      @inDocDecl = 2
    elsif data == ">"
      if !@extID.nil?
##            @current.nodeValue = @extID
      end
      @inDocDecl = 0
##          @current = @current.parentNode
    elsif data == "SYSTEM"
      @idRest = 1
      @extID = data
    elsif data == "PUBLIC"
      @idRest = 2
      @extID = data
    elsif data !~ /^\s+$/
      if @idRest > 0
        ## SysID or PubID
        @extID <<= " " + data
        @idRest -= 1
      else
        ## Root Element Type
        docType = data
##            doctype = DocumentType.new(nameConverter(docType))
##            @current.appendChild(doctype)
##            @current = doctype
      end
    end
  elsif @inDocDecl == 2
    if @inDecl == 0
      if data == "]"
        @inDocDecl = 1
      elsif data =~ /^<\!/
        @decl = data
        @inDecl = 1
      elsif data =~ /^%(.+);$/
        ## PERef
##            cdata = @document.createTextNode(nameConverter(data))
##            @current.appendChild(cdata)
      else
        ## WHITESPCAE
      end
    else ## inDecl == 1
      if data == ">"
        @decl <<= data
        @inDecl = 0
        ## Markup Decl
##            cdata = @document.createTextNode(cdataConverter(@decl))
        ## Markup decl should not be converted
##            @current.appendChild(cdata)
      elsif data =~ /^\s+$/
        ## WHITESPACE
        @decl << " "
      else
        @decl << data
      end
    end
  else
    ## maybe WHITESPACE
##        cdata = @document.createTextNode(cdataConverter(data))
##        @current.appendChild(cdata)
  end
end

#endCdataObject



213
214
215
216
217
218
219
# File 'lib/xml/dom/builder.rb', line 213

def endCdata
  return unless @createCDATASection
  cdata = @document.createCDATASection(cdataConverter(@cdata_buf))
  @current.appendChild(cdata)
  @cdata_buf = ''
  @cdata_f = false
end

#endElement(name) ⇒ Object



162
163
164
165
# File 'lib/xml/dom/builder.rb', line 162

def endElement(name)
  text
  @current = @current.parentNode
end

#externalEntityRef(context, base, systemId, publicId) ⇒ Object



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/xml/dom/builder.rb', line 179

def externalEntityRef(context, base, systemId, publicId)
  text
  tree = nil
  if @parse_ext
    extp = self.class.new(@level, self, context)
    extp.setBase(base) if base
    file = systemId
    if systemId !~ /^\/|^\.|^http:|^ftp:/ && !base.nil?
      file = base + systemId
    end
    begin
      tree = extp.parse(open(file).read, @parse_ext)
    rescue XML::ParserError
      raise XML::ParserError.new("#{systemId}(#{extp.line}): #{$!}")
    rescue Errno::ENOENT
      raise Errno::ENOENT.new("#{$!}")
    end
    extp.done
  end
  if @createEntityReference
    entref = @document.createEntityReference(nameConverter(context))
    @current.appendChild(entref)
    entref.appendChild(tree) if tree
  else
    @current.appendChild(tree) if tree
  end
end

#nameConverter(str) ⇒ Object

User redefinable name encoding converter



93
94
95
# File 'lib/xml/dom/builder.rb', line 93

def nameConverter(str)
  str
end

#parse(xml, parse_ext = false) ⇒ Object

Parse

doctree = parser.parse(xml, parse_ext)
  xml:       string or stream of XML contents
  parse_ext: flag whether parse external entities or not


124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/xml/dom/builder.rb', line 124

def parse(xml, parse_ext = false)
  if @external
    @tree = @document.createDocumentFragment
  else
    @tree = @document
  end
  @parse_ext = parse_ext
  @current = @tree
  @inDocDecl = 0
  @decl = ""
  @inDecl = 0
  @idRest = 0
  @extID = nil
  @cdata_f = false
  @cdata_buf = ''
  super(xml)
  @tree
end

#processingInstruction(name, data) ⇒ Object



171
172
173
174
175
176
177
# File 'lib/xml/dom/builder.rb', line 171

def processingInstruction(name, data)
  text
  pi = @document.createProcessingInstruction(nameConverter(name),
                                             cdataConverter(data))
  ## PI data should not be converted
  @current.appendChild(pi)
end

#startCdataObject



207
208
209
210
211
# File 'lib/xml/dom/builder.rb', line 207

def startCdata
  return unless @createCDATASection
  text
  @cdata_f = true
end

#startElement(name, data) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/xml/dom/builder.rb', line 150

def startElement(name, data)
  text
  elem = @document.createElement(nameConverter(name))
  data.each do |key, value|
    attr = @document.createAttribute(nameConverter(key))
    attr.appendChild(@document.createTextNode(cdataConverter(value)))
    elem.setAttributeNode(attr)
  end
  @current.appendChild(elem)
  @current = elem
end

#textObject



143
144
145
146
147
148
# File 'lib/xml/dom/builder.rb', line 143

def text
  return if @cdata_buf == ''
  textnode = @document.createTextNode(cdataConverter(@cdata_buf))
  @current.appendChild(textnode)
  @cdata_buf = ''
end