ruby on rails - XML Class for the partial file used in a Nokogiri class XML -
using rails 3.0.7 , ruby 1.9.2.
i using nokogiri build custom xml. calling partial builder file in main view file. class being used in partial xml not nokogiri. can explain why xml class not nokogiri ?
index.xml.erb
<%= nokogiri::xml::builder.new(:encoding => 'utf-8') { |xml| puts "xml class in main file #{xml.class}" xml.users { @users.each |user| xml << render(:partial=>"users/user", :locals=>{:user=>user, :xml => xml}) end } }.to_xml.html_safe %>
_user.builder
puts "xml class in builder file #{xml.class}" xml.user { xml.id user.id xml.name user.name xml.email user.email }
in application.rb, using :
activesupport::xmlmini.backend = 'nokogiri'
output :
xml class in main file nokogiri::xml::builder xml class in builder file builder::xmlmarkup
iiuc activesupport::xmlmini.backend = 'nokogiri'
parsing xml params nokogiri instead of rexml, not builder template generation.
you're creating nokogiri::xml::builder manually, relying on render
generate partial, therefore output consistent.
use following (in config/initializers/nokogiri_builders.rb
use nokogiri
via render (plus can stop using .xml.erb
files create own instance of nokogiri::xml::builder
, use .builder
too):
# config/initializers/nokogiri_builders.rb # using nokogiri::xml::builder in lieu of stock pure ruby builder rails builder templates module nokogiri module xml class builder # handle instruct! instead of emitting nonsense tag def instruct!(tag, options = {}) case tag when :xml @version = options[:version] @encoding = options[:encoding] else raise notimplementederror(tag.inspect) end end # redefined, recover instruct! gave def to_xml(*args) if nokogiri.jruby? options = args.first.is_a?(hash) ? args.shift : {} unless options[:save_with] options[:save_with] = node::saveoptions::as_builder end args.insert(0, options) end if @version || @encoding # set options according given args[0][:version] = @version if @version args[0][:encoding] = @encoding if @encoding # emit declaration args[0].delete(:save_with) end @doc.to_xml(*args) end end end end module actionview module template::handlers class builder # default format used builder. class_attribute :default_format self.default_format = :xml def call(template) require_engine code = <<-code builder = nokogiri::xml::builder.new |xml| #{template.source} end # default not emit declaration (use instruct! instead) save_options = nokogiri::xml::node::saveoptions::no_declaration # default utf-8, it's rails default encoding options = { encoding: 'utf-8', indent: 2, save_with: save_options } self.output_buffer = builder.to_xml(options) code code end protected def require_engine @required ||= begin require 'nokogiri' true end end end end end
watch out though, nokogiri builds full dom before generating output to_xml
, whereas builder concatenates strings on fly. might or might not want, large data sets. in both cases though, full final string resident in memory.
Comments
Post a Comment