gpt4 book ai didi

ruby-on-rails - Nokogiri 类 XML 中使用的部分文件的 XML 类

转载 作者:数据小太阳 更新时间:2023-10-29 08:04:45 25 4
gpt4 key购买 nike

使用 rails 3.0.7 和 ruby​​ 1.9.2。

我正在使用 Nokogiri 构建自定义 XML。我在主视图文件中调用部分构建器文件。但是部分用于 xml 的类不是 Nokogiri。谁能解释为什么 xml 类不是 Nokogiri?

索引.xml.erb

<%= Nokogiri::XML::Builder.new(:encoding => 'UTF-8') { |xml|
puts "xml class in main file #{xml.class}"
xml.users {
@users.each do |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
}

在 application.rb 中,使用:

ActiveSupport::XmlMini.backend = 'Nokogiri'

输出:

xml class in main file Nokogiri::XML::Builder
xml class in builder file Builder::XmlMarkup

最佳答案

IIUC ActiveSupport::XmlMini.backend = 'Nokogiri' 仅用于使用 Nokogiri 而非 ReXML 解析 XML 参数,不适用于构建器模板生成。

您正在手动创建一个 Nokogiri::XML::Builder,然后依靠 render 生成部分,因此您的输出是一致的。

使用以下(在 config/initializers/nokogiri_builders.rb 中)通过渲染实际使用 Nokogiri(另外你可以停止使用 .xml.erb 文件来创建您自己的 Nokogiri::XML::Builder 实例,并且也只需使用 .builder):

# config/initializers/nokogiri_builders.rb
# Using Nokogiri::XML::Builder in lieu of stock pure ruby Builder for 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, to recover what instruct! gave us
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 to what was given previously
args[0][:version] = @version if @version
args[0][:encoding] = @encoding if @encoding
# do emit a 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 by Builder.
class_attribute :default_format
self.default_format = :xml

def call(template)
require_engine
code = <<-CODE
builder = Nokogiri::XML::Builder.new do |xml|
#{template.source}
end
# default to not emit a declaration (use instruct! instead)
save_options = Nokogiri::XML::Node::SaveOptions::NO_DECLARATION
# default to UTF-8, as 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

不过请注意,Nokogiri 在使用 to_xml 生成输出之前会构建完整的 DOM,而 Builder 会动态连接字符串。这可能是也可能不是您想要的,尤其是对于大型数据集。不过在这两种情况下,完整的最终字符串都驻留在内存中。

关于ruby-on-rails - Nokogiri 类 XML 中使用的部分文件的 XML 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16663492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com