Wrapping XML document in Class

I would like to use Ruby and REXML to wrap an XML document and allow
access to the element nodes, attributes, and text. Essentially I need
an XML document builder loosely coupled from the document.

It seems like Ruby is powerful enough to code generate a class given an
XML document or build an object at run-time with the appropriate
accessors.

For instance:

order = XmlBuilder.new

order.add(“root”).add(“header”)
order.root.add(“body”)

order.body.add(“component”).attributes[“type”] = “metric”

order.write($stdout)

I’d also like to be able to plug-in input validation when assigning
values to elements and attributes.

Has anyone done this before?

Thanks.

Miles Monroe wrote:

I would like to use Ruby and REXML to wrap an XML document and allow
access to the element nodes, attributes, and text. Essentially I need
an XML document builder loosely coupled from the document.

It seems like Ruby is powerful enough to code generate a class given an
XML document or build an object at run-time with the appropriate
accessors.

For instance:

order = XmlBuilder.new

order.add(“root”).add(“header”)
order.root.add(“body”)

order.body.add(“component”).attributes[“type”] = “metric”

order.write($stdout)

I’d also like to be able to plug-in input validation when assigning
values to elements and attributes.

Has anyone done this before?

Thanks.

I found this blog entry on a XmlStringBuffer class in Ruby. I
understand using method_missing to create the element, but I’m not sure
how to closures would be implemented. Thanks.

http://www.beust.com/weblog/archives/000025.html

xml = XML.new

xml.html {
xml.head {
}
xml.body {
xml.table {
xml.tr {
xml.td({ “valign” => “top”}, “Content1”){
}
xml.td {
xml.append(“Content2”)
}
}
}
}
}

Miles Monroe wrote:

I would like to use Ruby and REXML to wrap an XML document and allow
access to the element nodes, attributes, and text. Essentially I need
an XML document builder loosely coupled from the document.

It seems like Ruby is powerful enough to code generate a class given an
XML document or build an object at run-time with the appropriate
accessors.

For instance:

order = XmlBuilder.new
[… example elided …]

Are you wanting to build a DOM object, or build a string containing XML
markup? If the later, Builder::XmlMarkup will do this. If the former,
it would be interesting to create a Builder with a similar API to
Buidler::XmlMarkup, but generated DOM trees instead of strings.

Or perhaps you are looking for something completely different.

XML Builder Link: http://builder.rubyforge.org/


– Jim W.

Hi Miles,

interesting idea, i did a quick (proof of concept) hack:

class Xmltree
attr_accessor :childs
attr_accessor :content
attr_accessor :attributes

def initialize
self.childs = []
self.attributes = {};
end

def method_missing meth, *args, &block
return attributes[args[0]] = args[1] if meth == :[]=
return attributes[args[0]] if meth == :[]
return self.content = args if meth == ‘=’.intern

unless child = childs.assoc(meth.to_s.chomp('='))
  childs << child = [meth.to_s.chomp('='), Xmltree.new]
end

return child[1] if meth.to_s[-1] != ?=
child[1].content = args

end

def to_s
childs.map do |t, c|
“”"<#{t} #{c.attributes.map do |a, v|
“#{a}=”#{v}""
end.join(’ ')}>\n#{c}</#{t}>\n"""
end.join + content.to_s + (content ? “\n” : ‘’)
end
end

usage:

xml = Xmltree.new

xml.header.title = ‘this is a demo’
xml.body.component[‘type’] = ‘the answer’
xml.body.component = 42

puts xml

output:

this is a demo 42 -------------------------------------------------------------

cheers

Simon

Miles Monroe:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/116822

http://www.rubyquiz.com/quiz34.html

I found a couple links on source filters for Ruby.

I guess what I was proposing was just something like this:

/html/head/title << “Implicit XML Document”

/html/body/h1 << “Ruby source filters”

/html/body/h1[“class”] = “golden”

/html/body/table[“id”] = “QueryResults”

puts $_implicit_XML

Simon Kröger wrote:

Hi Miles,

interesting idea, i did a quick (proof of concept) hack:

class Xmltree
attr_accessor :childs
attr_accessor :content
attr_accessor :attributes

def initialize
self.childs = []
self.attributes = {};
end

def method_missing meth, *args, &block
return attributes[args[0]] = args[1] if meth == :[]=
return attributes[args[0]] if meth == :[]
return self.content = args if meth == ‘=’.intern

unless child = childs.assoc(meth.to_s.chomp('='))
  childs << child = [meth.to_s.chomp('='), Xmltree.new]
end

return child[1] if meth.to_s[-1] != ?=
child[1].content = args

end

def to_s
childs.map do |t, c|
“”"<#{t} #{c.attributes.map do |a, v|
“#{a}=”#{v}""
end.join(’ ')}>\n#{c}</#{t}>\n"""
end.join + content.to_s + (content ? “\n” : ‘’)
end
end

usage:

xml = Xmltree.new

xml.header.title = ‘this is a demo’
xml.body.component[‘type’] = ‘the answer’
xml.body.component = 42

puts xml

output:

this is a demo 42 -------------------------------------------------------------

cheers

Simon

Miles Monroe:

Awesome! That is better than I ever imagined.

Back in my Perl days, I started creating a source filter to allow the
insertion of non-Perl XPath statements that worked on an implicit XML
document.

I used the source filter to first scan the code for naked XPath
statements and then built the XML document with the slightly-modified
XPath syntax. I converted the invalid non-Perl strings into valid Perl
in the source filter.

Likewise, is it possible to insert non-Ruby text in the main namespace
and then turn it into Ruby code before the rest of the script is parsed?
I guess I’m asking if it’s possible to implement a source filter in
Ruby.

Thanks.

Last time I was doing playing with XML, I wanted to be able to,
basically, add methods on to the nodes matching xpaths. It didn’t
seem to be very easy. I wondered at the time if some kind of
transform idea would work better.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs