Дополнительный <to_s /> при использовании компоновщика для генерации XML - PullRequest
11 голосов
/ 10 февраля 2011

Я пытаюсь сгенерировать KML с помощью Builder. Я знаю, что есть некоторые варианты, чтобы помочь с этим, но я буду делать некоторые специфичные для 2.2 вещи, которые не поддерживаются гемами KML, на которые я смотрел, и обычно хотел бы быть в состоянии сделать это, используя только структуру XML .

Я получаю тег в конце файла при рендеринге моего kml / xml. Я сильно подозреваю, что упускаю что-то простое с настройкой моего объекта Builder или с тем, как я отрисовываю вывод. Вот простой пример, демонстрирующий проблему:

def kml2dot2
  @site = Site.find(params[:id])
  xml = Builder::XmlMarkup.new(:indent => 2)
  xml.instruct!
  xml.kml("xmlns" => "http://www.opengis.net/kml/2.2") {
    xml.Placemark do
      xml.name @site.mapNameFull
      xml.Point do
        xml.coordinates @site.lat.to_s + "," + @site.lng.to_s + ",0"
      end
    end
  }
  render :text => xml, :type=>"text/kml"

end 

Производит:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
  <Placemark>
    <name>Seattle City Hall</name>
    <Point>
      <coordinates>47.6040746,-122.33005,0</coordinates>
    </Point>
  </Placemark>
</kml>
<to_s/>

Я пытаюсь понять, как избежать включения <to_s/> и что я делаю неправильно с Builder. Спасибо за понимание.

Ответы [ 2 ]

15 голосов
/ 01 апреля 2011

Мой короткий оригинальный ответ

Чтобы получить фактическое содержимое строки Builder, вам нужно вызвать метод target!

xml = Builder.new
# do your stuff...
xml.target! #returns the string
#where as calling most other methods (like to_s) to the builder object will just
#generate an element tag by that method name.


А потом немного более подробное объяснение того, что и почему происходит в случае ОП

Когда вы передаете объект построителя xml методу рендеринга, Rails автоматически вызывает для него метод to_s. Обычно это означает, что вам не нужно беспокоиться о типе данных, которые вы передаете для средства визуализации, так как они все равно будут преобразованы в строку. Очень удобно! Однако с объектом Builder вам необходимо выполнить преобразование самостоятельно, поскольку строитель предполагает, что любое отправленное ему сообщение является запросом на добавление нового элемента с именем. Поэтому вызов xml.to_s ведет себя так же, как вызов xml.kml, добавляет новый элемент. В этом случае вы не называете себя «1015», так что это не так очевидно и его легко пропустить. Простое решение этой проблемы - вызвать render так:

render :text => xml.target!, :type=>"text/kml"
2 голосов
/ 10 февраля 2011

Вам не нужно инициализировать объект XML-компоновщик.Просто используйте встроенный обработчик шаблона компоновщика.

  1. Вызовите шаблон kml2dot2.xml.builder
  2. Напишите код непосредственно в представлении

Пример

def kml2dot2
  @site = Site.find(params[:id])
end

# kml2dot2.xml.builder
xml.kml("xmlns" => "http:// www.opengis.net/kml/2.2") do
  xml.Placemark do
    xml.name @site.mapNameFull
    xml.Point do
       xml.coordinates "#{@site.lat},#{@site.lng},0"
    end
  end
end
...