xmlcodec - a XML importer/exporter framework for Ruby

What is this?

This is a framework to create importers/exporters of XML formats for Ruby. To create a new importer/exporter all you have to do is create a ruby class for each of the XML elements.

Where do I get it?

This project is hosted on RubyForge. You can see the project page or go straight to the files section to get the latest version. If you have RubyGems installed you can just do "gem install xmlcodec" and it will fetch the latest version from the network.

What features does it have?

The basic model of the framework is that an importer/exporter maps a XML tree into a Ruby object tree. To do this you write Ruby classes for each of the XML format's elements. After that you get several API's for free:

The first two API's treat the XML as a whole tree at once.

The stream parser allows you to parse a very big XML file as a stream but with more meaningfull events than a regular XML stream parser.

The partial export API allows you to create huge XML files the same way you'd create a small one (by putting elements in the Ruby tree) but without having to create the whole tree in memory. This is done by exporting an element into the output file and then removing it from the tree. This is not done automatically, but it's pretty easy to do.

How do I use it?

Look at the API docs for examples and full API of everything.

Some Examples Then?

Suppose you have this XML format:
  <root>
    <firstelement>
      <secondelement firstattr='1'>bar</secondelement>
      <secondelement firstattr='2'>foo</secondelement>
    </firstelement>
  </root>
To create an importer/exporter for it you'd write:
  require 'xmlcodec'

  class Root < XMLCodec::XMLElement
    elname 'root'
    xmlsubel :firstelement
  end

  class FirstElement < XMLCodec::XMLElement
    elname 'firstelement'
    xmlsubel_mult :secondelement
  end

  class SecondElement < XMLCodec::XMLElement
    elname 'secondelement'
    elwithvalue
    xmlattr :firstattr
  end
And that's it for the code you have to write. To import some xml you'd do:
  # From text
  Root.import_xml_text(File.new('file.xml'))
  
  # From a REXML DOM
  Root.import_xml(REXML::Document.new(File.new('file.xml')))
To generate some XML you can do:
  # To generate XML text
  string = some_element.xml_text

  # To generate REXML DOM
  doc = some_element.create_xml(REXML::Document.new)
Using the stream parser is also very easy:
  class MyStreamListener
    def el_secondelement(el)
      obj = el.get_object
    
      ... do something with obj ...
    
      # To remove it from the stream so the parent 
      # doesn't include it and memory is freed.
      el.consume
    end
  end
  
  parser = XMLStreamObjectParser.new(MyStreamListener.new)
  parser.parse(some_string_or_file)
The partial exporter is also pretty easy to use:
  file = File.new('somefile.xml')
  fe = FirstElement.new
  10000.times do |i|
    se = SecondElement.new(i)
    fe.secondelement << se
    se.partial_export(file)
  end
  fe.end_partial_export(file)