# Wrapping XML document in Class

**URL:** <https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736>\
**Category:** Ruby\
**Created:** [March 13, 2006, 8:21pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736 "2006-03-13T20:21:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 8:21pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/1 "2006-03-13T20:21:24Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 9:35pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/2 "2006-03-13T21:35:17Z")

</div>

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](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”)  
}  
}  
}  
}  
}

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 9:52pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/3 "2006-03-13T21:52:47Z")

</div>

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/](http://builder.rubyforge.org/)

–  
– Jim W.

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 10:16pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/4 "2006-03-13T22:16:40Z")

</div>

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:

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 11:03pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/5 "2006-03-13T23:03:22Z")

</div>

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

[http://www.rubyquiz.com/quiz34.html](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

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 13, 2006, 10:44pm UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/6 "2006-03-13T22:44:00Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Miles\_Monroe](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/58956e/32.png) [@Miles\_Monroe](https://www.ruby-forum.com/u/Miles_Monroe)\
**Post date:** [March 14, 2006, 12:12am UTC](https://www.ruby-forum.com/t/wrapping-xml-document-in-class/54736/7 "2006-03-14T00:12:46Z")

</div>

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.
