1

Is there a way to pass a string to an REXML::Element in such a way that the string will be parsed as XML, and the elements so found inserted into the target?

rampion
  • 87,131
  • 49
  • 199
  • 315

3 Answers3

2

You can extend the REXML::Element class to include innerHTML as shown below.

require "rexml/element"

class REXML::Element
  def innerHTML=(xml)
    require "rexml/document"
    self.to_a.each do |e|
      self.delete e
    end
    d = REXML::Document.new "<root>#{xml}</root>"
    d.root.to_a.each do |e|
      case e
      when REXML::Text
        self.add_text e
      when REXML::Element
        self.add_element e
      else
        puts "ERROR"
      end
    end
    xml
  end
  def innerHTML
    ret = ''
    self.to_a.each do |e|
      ret += e.to_s
    end
    ret
  end
end

You can then use innerHTML as you would in javascript (more or less).

require "rexml/document"
doc = REXML::Document.new "<xml><alice><b>bob</b><chuck>ch<u>u</u>ck</chuck></alice><alice/></xml>" 

c = doc.root.get_elements('//chuck').first
t = c.innerHTML
c.innerHTML = "#{t}<david>#{t}</david>"
c = doc.root.get_elements('//alice').last
c.innerHTML = "<david>#{t}</david>"

doc.write( $stdout, 2 )
G. Allen Morris III
  • 1,012
  • 18
  • 30
1

It would help if you could provide an example to further illustrate exactly what you had in mind.

With JS innerHTML you can insert text or HTML in one shot and changes are immediately displayed in the HTML document. The only way I know how to do this in REXML is with separate steps for inserting content/elements and saving/reloading the document.

To modify the text of a specific REXML Elemement you can use the text=() method.

#e represents a REXML Element
e.text = "blah"

If you want to insert another element you have to use the add_element() method.

#e represents a REXML Element
e.add_element('blah')      #adds <blah></blah> to the existing element
b = e.get_elements('blah') #empty Element named "blah"
b.text('some text')        #add some text to Element blah

Then of course save the XML document with the changes. ruby-doc.org/REXML/Element

rbnewb
  • 575
  • 5
  • 6
  • It's been a couple months since I posted the question, but I think what I wanted was basically JS's innerHTML functionality. I had some external XML that I wanted to just dump into an existing document, without having to parse it first. Ah well. – rampion May 31 '12 at 11:15
  • No worries. If you were thinking of dumping an external XML into an existing HTML document Javascript would be the way to go [w3schools.com](http://www.w3schools.com/dom/dom_loadxmldoc.asp). Otherwise you would create a new REXML Document by passing a string to __doc = Document.new('...')__ then write to a file with __doc.write(output=File.open('blah.xml','w'))__ – rbnewb May 31 '12 at 19:16
-1

text() will return the inner content as a string

Luke
  • 11,426
  • 43
  • 60
  • 69
Charles Barbier
  • 835
  • 6
  • 15