XmlParsable
XmlParsable is a simple means to declare how an XML grammar maps to Ruby objects. It does not perform validation of the input, and it is only able to describe fairly simple structures. It relies on LibXML::XML::SaxParser.
Quick Example
For more details, see the RSpec examples in spec/examples
.
Declare XML grammar
require "xmlparsable"
# Needed only for using the "collection" declaration or
# implement your own String#pluralize, String#singularize
require "active_support/core_ext"
class AddressBook
include XmlParsable
class Contact
include XmlParsable
element :givenname
element :familyname
element :phone
element :email
element :spouse, Contact
collection :children, Contact
element :birthdate, DateElement
element :updated, TimeElement
end
collection :contact, Contact
end
Parse input XML from string, IO, or File
book = AddressBook.parse(<<-XML)
<contacts>
<contact>
<familyname>Kim</familyname>
<givenname>Jong-il</givenname>
<birthdate>1942-02-16</birthdate>
<updated>2010-01-01T12:45:30</updated>
<children>
<child><givenname>Sul-song</givenname></child>
<child><givenname>Jong-chul</givenname></child>
<child><givenname>Jong-un</givenname></child>
<child>
<givenname>Jong-nam</givenname>
<spouse>
<givenname>Jong-hui</givenname>
<familyname>Shin</familyname>
</spouse>
</child>
</children>
</contact>
<contact>
<givenname>Vladimir</givenname>
<familyname>Putin</familyname>
<email>[email protected]</email>
<spouse>
<givenname>Lyudmila</givenname>
<familyname>Putina</familyname>
</spouse>
</contact>
</contacts>
XML
Iterate parsed data
kim, vlad = book.contacts
kim.givenname #=> "Kim"
kim.birthdate #=> #<Date: 4860813/2,0,2299161>
kim.updated #=> Fri Jan 01 12:45:30 2010
sulsong, jongchul, jongun, jongnam = kim.children
jongnam.spouse.givenname #=> "Jong-hui"
jongnam.spouse.familyname #=> "Shin"
vlad.email #=> "[email protected]"
vlad.spouse #=> #<AddressBook::Contact @givenname="Lyudmila" @familyname="Putina">
Data Types
DateElement
Parses content into a Ruby Date
object, using Date.parse
.
ListElement
Parses children nodes into an Array
using some other AbstractElement
child class.
NumericElement
Parses content into a Ruby Integer
or BigDecimal
, depending on whether
the input contains a decimal point or not. Parses using Integer(..)
and
BigDecimal(..)
constructor methods.
RecordElement
Parses children nodes according to element
and collection
declarations
on an XmlParsable
class.
StringElement
Parses content into a Ruby String
object.
TextElement
Concatenates all subordinate text nodes into a single String
. For example,
"abc def <b>what<!-- ever --></b>"
is read as "abc def what"
.
TimeElement
Parses content into a Ruby Time
object, using Time.parse
.
XmlElement
Parses children elements into an Array
whose elements are one of these three
classes. These really should be the same node types that LibXML
uses, but
that's not the case for now.
XmlParsable::Elements::XmlElement::Node
XmlParsable::Elements::XmlElement::Text
XmlParsable::Elements::XmlElement::Comment