Do it the simple way:
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>
The trick is add_child
, which can take a predefined node, or a string consisting of the XML you want to add. From the documentation:
Add node_or_tags as a child of this Node. node_or_tags can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
"a string containing markup" is a free-pass to doing it an easy way.
If you need a different value for the unit
parameter, or a different value for the tag itself, you can interpolate those into the string:
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>
Or you can directly modify the DOM and nodes:
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>
There are other ways to do this in addition, but it's really up to you to use whatever fits your head best.