如何在Nokogiri中创建具有属性和值的xml元素

时间:2014-09-30 10:11:46

标签: ruby-on-rails ruby xml nokogiri

我正在使用Rails 2.1.0和Nokogiri 1.6.1。我想要的东西看起来很简单。我希望我的Rails Rest API使用如下元素返回XML:

<PeopleNumber unit="NumberOfPeople">2.235075</PeopleNumber>

我尝试写过类似的东西:

xml = Nokogiri::NML::Builder.new do |xml|
  xml.PeopleNumber(:unit => "NumberOfPeople") 2.235075

ActionController会触发语法错误。

如果我尝试将其重写为

xml = Nokogiri::NML::Builder.new do |xml|
  xml.PeopleNumber(:unit => "NumberOfPeople") { 2.235075 }

我得到像

这样的东西
<PeopleNumber unit="NumberOfPeople" />

有没有人知道如何在Nokogiri中获得理想的行为?

3 个答案:

答案 0 :(得分:0)

以简单的方式做到:

require 'nokogiri'

doc = Nokogiri::XML('<foo></foo>')
doc.at('foo').add_child('<PeopleNumber unit="NumberOfPeople">2.235075</PeopleNumber>')
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >>   <PeopleNumber unit="NumberOfPeople">2.235075</PeopleNumber>
# >> </foo>

技巧是add_child,它可以采用预定义的节点,或者由您要添加的XML组成的字符串。来自文档:

  

将node_or_tags添加为此Node的子节点。 node_or_tags可以是Nokogiri :: XML :: Node,a :: DocumentFragment,a :: NodeSet或包含标记的字符串。

“包含标记的字符串”是一种免费通行证,可以轻松实现。

如果unit参数需要不同的值,或者标签本身需要不同的值,则可以将这些值插入到字符串中:

foo = 'WheelSize'
bar = '355/113'

doc = Nokogiri::XML('<foo></foo>')
doc.at('foo').add_child("<PeopleNumber unit='#{foo}'>#{bar}</PeopleNumber>")
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >>   <PeopleNumber unit="WheelSize">355/113</PeopleNumber>
# >> </foo>

或者您可以直接修改DOM和节点:

doc = Nokogiri::XML('<foo><PeopleNumber /></foo>')
people_number = doc.at('PeopleNumber')
people_number['unit'] = 'fred'
people_number.content = 'ethel'
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <foo>
# >>   <PeopleNumber unit="fred">ethel</PeopleNumber>
# >> </foo>

此外还有其他方法可以做到这一点,但是你最好还是选择最适合自己的方式。

答案 1 :(得分:0)

我刚刚在我的代码中找到了一种方法:

xml = Nokogiri::NML::Builder.new do |xml|
  child = xml.PeopleNumber 2.235075
  child["unit"] = "NumberOfPeople"

它生成了您所请求的适当XML。不确定是否对您有帮助,但是“简单”的答案不是我自己的功能代码的运行方式。

答案 2 :(得分:0)

我知道这是一个很老的问题,但是即使我偶然发现了同样的问题。
我找到了一个干净的解决方案。

{% for p in property %}
- {{ p }}
{% endfor %}

现在,如果您调试XML输出,您将获得正确的输出

builder = Nokogiri::NML::Builder.new do |xml|
  xml.PeopleNumber(2.235075, :unit => "NumberOfPeople")
end

说明: 当您想使用Nokogiri Builder将一些属性和文本内容设置为XML标记时,您需要直接将文本内容作为第一个参数传递,然后将其他属性作为键值对传递,就像我们传递给任何方法一样。

puts builder.to_xml
# output will be following
<PeopleNumber unit="NumberOfPeople">2.235075</PeopleNumber>

这将输出为

builder = Nokogiri::NML::Builder.new do |xml|
  xml.YourTagName(PLAIN_TEXT_CONTENT, attr1: value1, attr2: value2, attrN: valueN)
end

甚至还有其他方法,但这是最干净的方法。