Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Nokogiri to create XML element with namespace

Tags:

xml

ruby

nokogiri

I use Nokogiri that would create XML. I want to have the following structure:

<content:encode>text</content>

I have tried this code:

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

but it gives me an error.

How do I write this correctly? A similar example is in Referencing declared namespaces.

like image 805
Delaf Avatar asked Dec 21 '22 17:12

Delaf


1 Answers

  1. Your example doesn't make sense; you say that you want "encode" and then you attempt to write "encoded".

  2. Your example doesn't make sense, as it is not valid XML. You have an opening encode tag with the namespace content, and then you try to close it with a content tag. You want either <content:encode>text</content:encode> or you want <encode:content>text</encode:content>. (Which do you want?)

  3. You did not follow the example in the link you gave. If you want a content element with namespace encoded, then per the example you should write:

    xml['encoded'].content{ xml.text "text" }
    
  4. However, also per the example, you must declare any namespaces you want to reference. So do this:

    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>
    

Edit: If you really only need a single element with no root, using Nokogiri is overkill. Just do:

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

If you really need to use Nokogiri, but only want the first sub-root element, do:

xml_str = builder.doc.root.children.first.to_s
#=> "<encoded:content>text</encoded:content>"
like image 177
Phrogz Avatar answered Jan 06 '23 14:01

Phrogz