Skip to content

Instantly share code, notes, and snippets.

@rickhull
Created October 2, 2010 05:17
Show Gist options
  • Save rickhull/607336 to your computer and use it in GitHub Desktop.
Save rickhull/607336 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'nokogiri'
class PushDocument < Nokogiri::XML::SAX::Document
attr_reader :document, :current, :parents, :errors, :warnings
def cdata_block(string)
current << Nokogiri::XML::CDATA.new(document, string)
end
def characters(string)
current << Nokogiri::XML::Text.new(string, document)
end
def comment(string)
current << Nokogiri::XML::Comment.new(document, string)
end
def end_document
puts "END DOCUMENT!!!" # added
# ? TODO maybe add a document callback
end
def end_element(name)
puts "done with #{name}" # added
# TODO check current
pop
end
def end_element_namespace(name, prefix, url)
# TODO check current
pop
end
def error(str)
@errors << str
end
def start_document
@document = Nokogiri::XML::Document.new
@errors = []
@warnings = []
@current = @document
@parents = [@document.root]
end
def start_element(name, attrs = [])
puts "got #{name}" # added
e = Nokogiri::XML::Element.new(name, document)
# attrs.each { |a| e.add_child a } # removed, causes error
push e
end
def start_element_namespace(name, attrs=[], prefix=nil, uri=nil, ns=[])
start_element(name, attrs)
# TODO apply namespace stuff to current
end
def warning(string)
@warnings << string
end
def xmldecl(version, encoding, standalone)
document.encoding = encoding
# TODO can we do anything about version and standalone?
end
def push(cur)
parents.push current
@current = cur
end
def pop
new_cur = parents.pop
new_cur.add_child current
@current = new_cur
end
def to_xml(*a)
document.to_xml(*a)
end
def to_html(*a)
document.to_html(*a)
end
def done?
p current # added
p document # added
return false unless current && document
# p document.root # added
current == document.root
end
end
class EasyPush < Nokogiri::XML::SAX::PushParser
def initialize(doc = PushDocument.new, *args)
super
end
def done?
document.done?
end
end
BEGIN { require 'rubygems' if __FILE__ == $0 }
if __FILE__ == $0
require 'pp'
ep = EasyPush.new
ep << ARGF.read(1) until ARGF.eof? # or ep.done? # ep.done? is always false :/
puts "done? #{ep.done?}" # added
puts ep.document.to_xml
p ep.document.errors
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment