AXML
AXML - Provides a simple DOM for working with XML (using XMLParser under the hood) that can serve as a drop in replacement for a subset of basic libxml functionality (e.g., each, children, child, find_first, find, next).
‘AXML’ means ‘ax XML’ which succinctly describes the occasional feeling of a programmer towards XML or its myriad parsers. AXML won’t solve all your problems, but it does make working with XML much less painful.
Features
-
fast: it’s implemented in XMLParser (expat under the hood)
-
lean: as in ‘lines of code’ (~220 w/ blank lines) and as in ‘memory consumption’ (nodes implemented as Struct, children in Array)
-
*easy to extend*: code your Grandmother could read and understand (if she reads ruby)
-
*quacks like libxml*: implements a very useful subset of libxml methods for near drop in replacement.
Examples
require 'axml' # currently requires 'xmlparser' be installed
# Windows: already in one-click-installer
# Ubuntu: sudo apt-get install libxml-parser-ruby1.8
# Cygwin: see http://mspire.rubyforge.org/tutorial/cygwin_mspire.html
# a little example xml string to use
string_or_io = "
<n1>
<n2 size='big'>
<n3>words here</n3>
<n3></n3>
</n2>
<n2 size='small'>
<n3 id='3'></n3>
</n2>
</n1>
"
### Read a string or io
n1_node = AXML.parse(string_or_io)
### Read a file
n1_node = AXML.parse_file('path/to/file')
### Access children
n1_node.children # -> [array]
n1_node.each {|child| # do something with child }
### Get attributes and text
n2_node['size'] == 'big'
n3_node = n2_node.child
n3_node.text # -> 'words here'
n3_node.content # -> [same]
### Traverse nodes with next and child
n2_node = n1_node.child
the_other_n2_node = n2_node.next
the_other_n2_node.next = nil
### Does a little xpath
# find_first (returns the first node)
n3_node = n1_node.find_first('descendant::n3')
other_n3_node = n3_node.find_first('following-sibling::n3')
n1_node.find_first('child::n3') # -> nil
# find (returns an array)
n1_node.find('descendant::n3') # -> [array of all 3 <n3> nodes]
n1_node.find('child::n2') # -> [array of 2 <n2> nodes]
### Switch to libxml
This is all it takes to get all of the above code to work under libxml:
require 'xml/libxml' # instead of: require 'axml'
# A file
REPLACE: n1_node = AXML.parse_file(file)
WITH: n1_node = XML::Document.file(file).root # note the .root call on the end!
# A string
REPLACE: n1_node = AXML.parse(string)
WITH: n1_node = XML::Parser.string(string).parse.root # note the .root call on the end!
Wallah! All the above method calls work under libxml
See ‘specs/axml_spec.rb` for more examples and functionality
Detailed Description
Parses elements, attributes, and text(content), and nothing more. Should be very easy to extend and modify for special cases. It is roughly as fast as libxml, although it currently reads in the entire document first (however, this is memory efficient - nodes are implemented using Struct).
Installation
gem install axml