使用构建器生成XML </to_s>时的额外<to_s>

时间:2011-02-10 19:22:05

标签: ruby-on-rails xml kml builder

我正在尝试使用Builder生成KML。我知道他们有一些选择可以帮助解决这个问题,但是我会做一些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 个答案:

答案 0 :(得分:15)

我简短的原始答案

要获取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构建器对象传递给render方法时,Rails将自动为其调用to_s方法。通常,这意味着您无需担心为渲染器传递的数据类型,因为无论如何它都将转换为String。很方便!但是,使用Builder对象时,您需要自行进行转换,因为构建器假定发送给它的任何消息都是通过名称添加新元素的请求。因此,调用xml.to_s的行为与调用xml.kml的行为相同,添加了一个新元素。在这种情况下,你没有打电话给to_s你自己,所以它不那么明显,很容易错过。对此的简单修复就是像这样调用render

render :text => xml.target!, :type=>"text/kml"

答案 1 :(得分:2)

您无需初始化XML构建器对象。只需使用集成的构建器模板处理程序。

  1. 调用模板kml2dot2.xml.builder
  2. 直接在视图中编写代码
  3. 实施例

    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