Generic XML Parsing in RubyMotion With NSXMLParser
I've been working a lot with NSXMLParser objects returned by AFMotion lately, and I couldn't find too much about how to use its delegate style of parsing. I figured I'd share the love with this generic parser. It doesn't take into account namespaces or anything, but this is a good simple base if you need one.
class XMLParserDelegate
attr_reader :root
def initialize
@root = nil
@queue = []
end
def parser(parser, didStartElement:elementName, namespaceURI:namespaceURI, qualifiedName:qualifiedName, attributes:attributeDict)
el = XMLElement.new(elementName, attributeDict)
if @queue.empty?
@root = el
else
@queue[-1].add_child(el)
end
@queue << el
end
def parser(parser, didEndElement:elementName, namespaceURI:namespaceURI, qualifiedName:qName)
@queue.pop
end
end
class XMLElement
attr_accessor :name, :attributes, :children
def initialize(name, attributes)
@el = name
@attributes = attributes
@children = []
end
def add_child(el)
@children << el
end
def to_xml
if @children.empty?
'<' + @el + attrs_as_xml + '/>'
else
'<' + @el + attrs_as_xml + '>' + @children.map(&:to_xml).join + '</' + @el + '>'
end
end
private
def attrs_as_xml
@attributes.map { |k, v| ' ' + k.to_s + '="' + v.to_s + '"' }.join
end
end
Used like this (for example on the REPL):
(main)> AFMotion::XML.get('http://example.com/test.xml') do |result|
parser = result.object
end
=> #<AFXMLRequestOperation:0xa0d6490>
(main)> parser.delegate = XMLParserDelegate.new
=> #<XMLParserDelegate:0xa0d8900 @root=nil @queue=[]>
(main)> parser.parse
=> 1
(main)> parser.delegate.root
=> #<XMLElement:....>
There are plenty of other NSXMLParserDelegate callbacks to check out, so take a look.
Written by Brendan Caffrey
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Nsxmlparser
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#