XML::Mapping and text nodes with attributes
While working on an API interface I’ve been playing around with XML::Mapping, an XML-to-object wrapper for ruby. The main reason to use it is that it allows me to easily build an interface similar to that used in Cody Fauser’s Ebay API client which will also be used in the same application.
Generally I’ve been very happy with the library, though at some point it would be nice to have a class generator which will take the XSD file and write most of the code for me, but scour the documentation as I may I couldn’t find an easy way to add attributes to a standard text-holding node. It’s easy enough to get:
<company> <person id="123"> <name>First Person</name> </person> </company>
I couldn’t find a way to get:
<company> <person id="123">First Person</person> </company>
without resorting to xpath wrangling.
Thankfully the library allows you to define your own node types, so once I added
module XML module Mapping class TextNodeWithAttributes < SingleAttributeNode def initialize_impl(path) @path = XML::XXPath.new(path) end def extract_attr_value(xml) default_when_xpath_err{ @path.first(xml).text } end def set_attr_value(xml, values) @path.first(xml, :ensure_created=>true).text = values.delete(:value) @path.first(xml, :ensure_created=>true).add_attributes(values) unless values.empty? end end end end
to my code and then included it with
XML::Mapping.add_node_class XML::Mapping::TextNodeWithAttributes
I could specify the above with the class:
module MyNamespace class Company text_node_with_attributes :person, 'person' end end
and create it with
MyNamespace::Company.new(:person => {:value => 'My Person', 'id' => '123'})
Comments are closed.