I recently had to do some work supplying an XML feed for a client. I used Ruby’s built-in .to_xml on the array of ActiveRecord objects and it generated this XML which I was happy with:
<vehicles> <vehicle> <date type="date">2012-04-17</date> <status>passed</status> <certificate-number nil="true"></certificate-number> <certified-at type="datetime">2012-04-18T07:23:00Z</certified-at> <vin>33333333333333333</vin> </vehicle> </vehicles>
Nice and simple.
Unfortunately, the organisation that was consuming this XML wanted an XSD. And provided one. But it required the namespace xsi for nil values (replacing the
nil="true" above with
xsi:nil="true". I thought this would be an easy change…
It is not possible to provide settings to Rails’ to_xml to include the namespace attribute
xmlns:xsi="http://..." into the <vehicles> tag so that it could be used wherever there were nil values.
It seem it is impossible to get an XSD to support the XML as supplied.
As a result I had to manually build the xml using builder. Now sure, there’s nothing particularly complex about this XML, but now I needed to write xml.builder views and write my own xml tag helper to identify nil/blank values and put in the appropriate attribute:
def nil_tag(tag, value) if value.nil? || value.blank? @xml.tag!(tag, value, 'xsi:nil' => true) else @xml.tag!(tag, value) end end
I also then had to format my DateTime output as .xmlschema as the default to_s is not valid in XML. Added an extra day of work all because the XSD couldn’t describe the XML I had.
I should have insisted on JSON.