使用Nokogiri创建带有命名空间的XML元素

时间:2011-02-16 12:06:35

标签: ruby xml nokogiri

我使用会创建XML的Nokogiri。我想拥有以下结构:

<content:encode>text</content>

我试过这段代码:

xml.content['encoded'] {xml.text "text"}

但它给了我一个错误。

如何正确写这个?类似的示例位于 Referencing declared namespaces

1 个答案:

答案 0 :(得分:11)

  1. 你的榜样没有意义;你说你想要“编码”,然后你尝试写“编码”。

  2. 您的示例没有意义,因为它不是有效的XML。您有一个包含名称空间encode的开始content标记,然后您尝试使用content标记将其关闭。您想要<content:encode>text</content:encode>或者想要<encode:content>text</encode:content>(你想要哪个?)

  3. 您没有按照您提供的链接中的示例进行操作。如果你想要一个content元素与命名空间encoded,那么按照你应该写的例子:

    xml['encoded'].content{ xml.text "text" }
    
  4. 但是,根据示例,您还必须声明要引用的任何名称空间。所以这样做:

    require 'nokogiri'
    
    builder = Nokogiri::XML::Builder.new do |xml|
      xml.root('xmlns:encoded' => 'bar') do
        xml['encoded'].content{ xml.text "text" }
      end
    end
    puts builder.to_xml
    #=> <?xml version="1.0"?>
    #=> <root xmlns:encoded="bar">
    #=>   <encoded:content>text</encoded:content>
    #=> </root>
    
  5. 编辑:如果你真的只需要一个没有root的单个元素,那么使用Nokogiri就太过分了。只是做:

    str = "Hello World"
    xml = "<encoded:content>#{str}</encoded:content>"
    puts xml
    #=> <encoded:content>Hello World</encoded:content>
    

    如果你真的需要使用Nokogiri,但只想要第一个子根元素,请执行:

    xml_str = builder.doc.root.children.first.to_s
    #=> "<encoded:content>text</encoded:content>"