I am currently preparing an article about Ruby and XML where I will
show some XML modules for ruby. only a short example to show
people what’s possible and that Ruby is a great alternative to Java/C#
when processing XML.
I am searching for a module where I can construct a Ruby Class from
an arbitrary XML document, similar to Python’s anobind
with this I can take an XML document like this
…
and this python code
#!/usr/bin/env python
import anobind
Here’s something that’ll do the job. I just threw this together, so
it is probably fragile, and it is one-way – it only converts XML to
Ruby objects. But it implements the functionality that you described
in the example you gave – it does so in 25 lines of code, and took
about as many minutes to write and test. I’m sure it could be
compressed and/or optimized; there were a number of solutions to
choose from.
By the way, I personally believe that this class of XML-to-Objects
mechanism has extremely limited use. If you use real XML objects and
XPath, you have access to a much broader set of XML documents, and it
is often easier to work with – especially with deeply nested XML.
And if all you’re looking for is serialization, there are a number of
projects available; some, even, that generate XML – albeit, not as
clear of a 1-to-1 mapping as here.
For an example of where I expect the Python code to fail (and I know
the Ruby code I’ve supplied will fail), given:
How do you differentiate between @b and b? Can you get any of the TAG
text values?
Anyway, here’s the Ruby version of the Python module.
############## START CODE
A quasi-serialization class. Accepts a limited subset of XML and
turns it
into Ruby objects.
require “rexml/document”
class XMLObject
def initialize element @element = element @methods = {}
end
def method_missing method
m_name = method.to_s
return @methods[m_name] if @methods[m_name]
el = REXML::XPath.match( @element, m_name )
case el.size
when 0
return @element.attributes[ m_name ]
when 1 @methods[ m_name ] = XMLObject.new( el[0] )
else
el.collect!{ |e| XMLObject.new( e ) } @methods[ m_name ] = el
end
return @methods[m_name]
end
def to_s
return REXML::XPath.match( @element, “text()” ).join.squeeze("
\n\t").strip
end
end
Cut here if you want to reuse this code. Everything that follows is
with this I can take an XML document like this
…
and this python code
#!/usr/bin/env python
import anobind
Here’s something that’ll do the job. I just threw this together, so
it is probably fragile, and it is one-way – it only converts XML to
Ruby objects. But it implements the functionality that you described
in the example you gave – it does so in 25 lines of code, and took
about as many minutes to write and test. I’m sure it could be
compressed and/or optimized; there were a number of solutions to
choose from.
By the way, I personally believe that this class of XML-to-Objects
mechanism has extremely limited use. If you use real XML objects and
XPath, you have access to a much broader set of XML documents, and it
is often easier to work with – especially with deeply nested XML.
And if all you’re looking for is serialization, there are a number of
projects available; some, even, that generate XML – albeit, not as
clear of a 1-to-1 mapping as here.
For an example of where I expect the Python code to fail (and I know
the Ruby code I’ve supplied will fail), given: