代码之家  ›  专栏  ›  技术社区  ›  JasonSmith

无漂亮打印的Rails XML生成器(即缩小的XML)

  •  3
  • JasonSmith  · 技术社区  · 15 年前

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

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

    例如,此代码:

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

    正在生产:

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

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

    那么,我怎样才能完全消除打印呢?目前,我正在考虑使用monkey patching Builder::XmlMarkup,以便initialize忽略 :缩进 参数;虽然我也在考虑使用后过滤器。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Matt    15 年前

    使命感 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>
    
        2
  •  0
  •   JasonSmith    15 年前

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

    1. (我目前的解决方案)制作一个简单的插件,让monkey补丁ActionView::TemplateHandlers::Builder强制0缩进(根据Matt的回答)。不幸的是,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,验证它并执行任何其他必要的操作。这是机架中间件的一个很好的候选者。因此,最终我预见自己将编写一个简单的框架中间件层,该层将验证传出的XML(如果无效,则发出警报,等等),然后在开发模式下漂亮地打印它,或者在生产中压缩它。