Skip to content

Instantly share code, notes, and snippets.

@julien51
Created April 24, 2009 21:47
Show Gist options
  • Save julien51/101354 to your computer and use it in GitHub Desktop.
Save julien51/101354 to your computer and use it in GitHub Desktop.
module Babylon
##
# This is the XML SAX Parser that accepts "pushed" content
class XmppParser < Nokogiri::XML::SAX::Document
attr_accessor :elem, :doc, :parser
##
# Initialize the parser and adds the callback that will be called upon stanza completion
def initialize(callback)
super()
reset
end
##
# Resets the Pushed SAX Parser.
def reset
@parser = Nokogiri::XML::SAX::PushParser.new(self, "UTF-8")
@elem = @doc = nil
end
##
# Pushes the received data to the parser. The parser will then callback the document's methods (start_tag, end_tag... etc)
def push(data)
@parser << data
end
##
# Adds characters to the current element (being parsed)
def characters(string)
end
##
# Instantiate a new current Element, adds the corresponding attributes and namespaces.
# The new element is eventually added to a parent element (if present).
# If no element is being parsed, then, we create a new document, to which we add this new element as root. (we create one document per stanza to avoid memory problems)
def start_element(qname, attributes = [])
@doc ||= Nokogiri::XML::Document.new
@elem ||= @doc # If we have no current element, then, we take the doc
@elem = @elem.add_child(Nokogiri::XML::Element.new(qname, @doc))
if @elem.name == "stream:stream"
# We activate the callback since this element will never end.
@doc = @elem = nil # Let's prepare for the next stanza
end
end
##
# Terminates the current element and calls the callback
def end_element(name)
if @elem
if @elem.parent == @doc
# If we're actually finishing the stanza (a stanza is always a document's root)
# We delete the current element and the doc (1 doc per stanza policy)
@elem = @doc = nil
@parser = Nokogiri::XML::SAX::PushParser.new(self, "UTF-8")
else
@elem = @elem.parent
end
else
# Not sure what to do since it seems we're not processing any element at this time, so how can one end?
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment