3

我正在使用 Builder::XmlMarkup 为 RESTful API 服务器生成 XML 格式的数据结构。

最近,我发现了一个错误,其中来自 Builder::XmlMarkup 的漂亮打印产生了一个充满空白文本的元素,而不是应有的空元素。

例如,这段代码:

xml.outertag do
  xml.list do
    # Some code which loops through a list
  end
end

正在生产:

<outertag>
  <list>
  </list>
</outertag>

当内部列表为空列表时,元素必须为空——即<list/> 或<list></list>。然而,实际的 XML 是一个 <list> 标记,其中填充了换行符和其他空格。

那么,我怎样才能完全消除 Builder 的漂亮打印呢?目前,我正在考虑猴子修补 Builder::XmlMarkup 以便初始化忽略:indent参数;虽然我也在考虑使用 after_filter。

4

2 回答 2

3

完全没有任何缩进参数的调用Builder::XmlMarkup.new不应该给你任何空格。

xml = Builder::XmlMarkup.new
xml.outertag do
  xml.list do
    # Some code which loops through a list
  end
end

xml # => <outertag><list></list></outertag>
于 2009-08-22T14:30:30.843 回答
0

接受马特的回答,因为它似乎是最普遍适用的。然而,由于我的情况是一个为每个URL输出 XML 的 API ,我想要一个全面工作的东西。

这里有两个解决方案:

  1. (我目前的解决方案)制作一个简单的插件,猴子补丁 ActionView::TemplateHandlers::Builder 强制0缩进(根据马特的回答)。不幸的是,ActionView::TemplateHandlers::Builder 主要是一个不透明的 Ruby 代码字符串,稍后会进行 eval() 处理。这是我的主要模块,其中包括:

    module MinimalXml
      module Builder
        def self.included(base)
          base.class_eval do
            def compile(template)
              indent = 0
              "_set_controller_content_type(Mime::XML);" +
                "xml = ::Builder::XmlMarkup.new(:indent => #{indent});" +
                "self.output_buffer = xml.target!;" +
                template.source +
                ";xml.target!;"
            end
          end
        end
      end
    end
    
  2. (可能是未来的解决方案。)我突然想到,一个严肃的基于 XML 的 Web 服务需要处理传入和传出的 XML,对其进行验证并执行其他任何必要的操作。这是 Rack 中间件的理想选择。因此,最终我预见自己会编写一个简单的 Rack 中间件层,该层将验证传出的 XML(如果它无效,则发出警报等),然后在开发模式下将其漂亮地打印出来,或者在生产中对其进行压缩。

于 2009-09-28T05:12:58.257 回答