Created
April 17, 2010 13:35
-
-
Save julik/369543 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# An XML writer for Ruby's XML RPC module | |
require 'rubygems' | |
require 'builder' | |
# The default XML serializer in Ruby's XML RPC module is VERY sloppy. | |
# We use Jim Weirich's excellent Builder to generate clean XML, even though it costs us some extra | |
# performance | |
class RPCBuilder | |
# This is what is going to be lugged around as XML RPC results. It's actually | |
# a node element | |
class Command | |
attr_accessor :text, :name, :children | |
def initialize | |
@text, @name, @children = nil, nil, [] | |
yield(self) if block_given? | |
end | |
def inspect | |
'<#Command @name=%s @text=%s @children=%s' % [ name, text, children.length] | |
end | |
end | |
# Should return a prebaked element. It saves us that native Builder uses tag! | |
def tag(name, txt) | |
Command.new { | c | c.name = name; c.text = txt } | |
end | |
def document_to_str(command_tree) | |
@builder = Builder::XmlMarkup.new | |
@builder.instruct! | |
# Play the command tree to builder inside, do not run twice | |
command_to_builder_call(command_tree) | |
@builder.target! | |
end | |
# Make a document and stuff things into it. Document is actually a nothing thing. | |
def document(*stuff) | |
stuff | |
end | |
# noop, a processing instruction | |
def pi(name, *params); end | |
def ele(name, *children) | |
# Make an element with name and attributes | |
Command.new { |c| c.name = name; c.children = children } | |
end | |
# Should return the text escaped as XML cdata | |
def text(txt) | |
Command.new { |c| c.text = txt } | |
end | |
private | |
# This will convert a tree of commands into XML Builder calls | |
def command_to_builder_call(cmd) | |
case cmd | |
when NilClass | |
# pass | |
when Array | |
cmd.compact.each{|c| command_to_builder_call(c) } | |
when Command | |
if cmd.name | |
@builder.tag!(cmd.name) { @builder.text!(cmd.text.to_s.strip) if cmd.text; command_to_builder_call(cmd.children) } | |
else | |
@builder.text!(cmd.text) | |
end | |
when String | |
@builder.text!(cmd.strip) unless cmd.empty? | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment