Rails XML Builder без симпатичной печати (т.е. минимизированный XML) - PullRequest
3 голосов
/ 22 августа 2009

Я использую Builder :: XmlMarkup для создания структур данных в формате XML для сервера API RESTful.

Недавно я обнаружил ошибку, из-за которой симпатичная печать из Builder :: XmlMarkup выдает элемент, заполненный пробельным текстом вместо пустого элемента, как и должно быть.

Например, этот код:

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

производит:

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

Если внутренний список является пустым списком, элемент должен быть пустым, т.е. или . Однако фактический XML - это тег , заполненный новой строкой и другими пробелами.

Итак, как мне вообще исключить красивую печать Builder? В настоящее время я думаю о monkey-patching Builder :: XmlMarkup, чтобы при инициализации игнорировались параметры : indent ; хотя я рассматриваю также постфильтр.

Ответы [ 2 ]

3 голосов
/ 22 августа 2009

Вызов 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>
0 голосов
/ 28 сентября 2009

Принятие ответа Мэтта как наиболее распространенного. Однако, поскольку моя ситуация - это API, который выводит XML для каждого URL, я хочу что-то, что работает по всем направлениям.

Вот два решения для этого:

  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 должен обрабатывать входящий и исходящий XML, проверять его и делать все остальное, что необходимо. Это хороший кандидат на промежуточное программное обеспечение Rack. Так что в конце концов я предвижу, что напишу простой промежуточный слой Rack, который будет проверять исходящий XML-код (подавать сигнал тревоги, если он недействителен и т. Д.), А затем либо просто распечатывать его, если он находится в режиме разработки, либо сжимать его в процессе производства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...