Экстра <to_s/"> при использовании построителя для генерации XML
Я пытаюсь создать 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. Спасибо за понимание.
Ответы
Ответ 1
Вам не нужно инициализировать объект построителя XML. Просто используйте обработчик шаблона встроенного построителя.
- Вызвать шаблон kml2dot2.xml.builder
- Напишите код непосредственно в представлении
Пример
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
Ответ 2
Мой короткий исходный ответ
Чтобы получить фактическое содержимое строки 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.
И затем немного более подробное объяснение того, что и почему происходит в случае OPs
Когда вы передаете объект-конструктор xml
в метод рендеринга, Rails автоматически вызовет для него метод to_s
. Обычно это означает, что вам не нужно беспокоиться о типе данных, которые вы передаете для средства визуализации, так как в любом случае он будет преобразован в String. Очень удобно! Однако с объектом Builder вам нужно сделать преобразование самостоятельно, так как строитель предполагает, что любое отправленное ему сообщение - это запрос на добавление нового элемента по имени. Поэтому вызов xml.to_s
ведет себя так же, как вызов xml.kml
, добавляет новый элемент. В этом случае вы не называете to_s
своим "я", поэтому это не так очевидно и легко пропустить. Простым решением для этого является вызов render
следующим образом:
render :text => xml.target!, :type=>"text/kml"