Rectangle 27 1

ruby Adding namespace using Nokogiri's XML Builder?


<?xml version="1.0"?>
   <root xmlns:foo="bar" xmlns="default">
     <tenderlove/>
   </root>
builder = Nokogiri::XML::Builder.new { |xml|
     xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
       xml.tenderlove
     end
   }
   puts builder.to_xml
# This happens to work for now, but I doubt you should rely upon it.
builder.doc.root.name = "p:ACMRequest"
<p:ACMRequest xmlns:p=""></p:ACMRequest>
builder = Nokogiri::XML::Builder.new { |xml|
  xml.ACMRequest(NS) do
   xml.parent.namespace =  # find the ns in xml.parent.namespace_definitions
   # 
  end
end
require 'nokogiri'
NS = {
  "xmlns:p"   => "http://www.acme.com",
  "xmlns:p1"  => "http://www.acme.com/datatypes",
  "xmlns:p2"  => "http://www.acme.com/ACMRequestdatatypes",
  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
}
builder = Nokogiri::XML::Builder.new { |xml|
  xml.ACMRequest(NS) do
    xml.GetQuote
  end
}
puts builder.to_xml

#=> <?xml version="1.0"?>
#=> <ACMRequest xmlns:p="http://www.acme.com" xmlns:p1="http://www.acme.com/datatypes" xmlns:p2="http://www.acme.com/ACMRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#=>   <GetQuote/>
#=> </ACMRequest>
root = builder.doc.root
acme = root.namespace_definitions.find{ |ns| ns.href==NS["xmlns:p"] }
root.namespace = acme
puts builder.to_xml

#=> <?xml version="1.0"?>
#=> <p:ACMRequest xmlns:p="http://www.acme.com" xmlns:p1="http://www.acme.com/datatypes" xmlns:p2="http://www.acme.com/ACMRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">atypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#=>   <GetQuote/>
#=> </p:ACMRequest>

@muistooshort No; the first four blocks (quote, code, quote, code) are all from the page. I'll indent them all for increased clarity.

As for the namespace prefix on the root element itself

Congratulations, now the first hit on Google for that is this page.

I cannot figure out how to apply a namespace prefix to the first element in Nokogiri during creation. Instead, you have to apply the namespace after creating the document:

It looked like an editing mistake but it was just a Markdown artifact. You can make a "code block inside a blockquote" work if you use enough leading spaces on the code block and enough > for the blockquote. I think I fixed it, I'm just feeling a bit OCD this morning

Namespaces are added similarly to attributes. Nokogiri::XML::Builder assumes that when an attribute starts with xmlns, it is meant to be a namespace:

Sorry for the late response. @Phrogz thanks for your extensive response. My experience with XML has been rather limited but your response did clear up a few other questions I had as well. I have lost count of how many times I have looked at the Nokogiri documentation but its not till someone else explains it that things makes sense. :-) yup i did notice the typo in the code block too :-)

Note
Rectangle 27 1

ruby Adding namespace using Nokogiri's XML Builder?


<?xml version="1.0"?>
<p:ACMRequest xmlns:p="http://www.acme.com" xmlns:p1="http://www.acme.com/datatypes" xmlns:p2="http://www.acme.com/ACMRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <p:GetQuote/>
</p:ACMRequest>
require 'nokogiri'
NS = {
  "xmlns:p"   => "http://www.acme.com",
  "xmlns:p1"  => "http://www.acme.com/datatypes",
  "xmlns:p2"  => "http://www.acme.com/ACMRequestdatatypes",
  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
}
builder = Nokogiri::XML::Builder.new { |xml|
  xml['p'].ACMRequest(NS) do
    xml.GetQuote
  end
}
puts builder.to_xml

Tags that reference non-default namespaces (i.e. a tag foo:bar) can be built by using the Nokogiri::XML::Builder#[] method.

This works fine with nokogiri 1.6.1, but not 1.5.6.

Note
Rectangle 27 1

ruby Adding namespace using Nokogiri's XML Builder?


<?xml version="1.0"?>
   <root xmlns:foo="bar" xmlns="default">
     <tenderlove/>
   </root>
builder = Nokogiri::XML::Builder.new { |xml|
     xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do
       xml.tenderlove
     end
   }
   puts builder.to_xml
# This happens to work for now, but I doubt you should rely upon it.
builder.doc.root.name = "p:ACMRequest"
<p:ACMRequest xmlns:p=""></p:ACMRequest>
builder = Nokogiri::XML::Builder.new { |xml|
  xml.ACMRequest(NS) do
   xml.parent.namespace =  # find the ns in xml.parent.namespace_definitions
   # 
  end
end
require 'nokogiri'
NS = {
  "xmlns:p"   => "http://www.acme.com",
  "xmlns:p1"  => "http://www.acme.com/datatypes",
  "xmlns:p2"  => "http://www.acme.com/ACMRequestdatatypes",
  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
}
builder = Nokogiri::XML::Builder.new { |xml|
  xml.ACMRequest(NS) do
    xml.GetQuote
  end
}
puts builder.to_xml

#=> <?xml version="1.0"?>
#=> <ACMRequest xmlns:p="http://www.acme.com" xmlns:p1="http://www.acme.com/datatypes" xmlns:p2="http://www.acme.com/ACMRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#=>   <GetQuote/>
#=> </ACMRequest>
root = builder.doc.root
acme = root.namespace_definitions.find{ |ns| ns.href==NS["xmlns:p"] }
root.namespace = acme
puts builder.to_xml

#=> <?xml version="1.0"?>
#=> <p:ACMRequest xmlns:p="http://www.acme.com" xmlns:p1="http://www.acme.com/datatypes" xmlns:p2="http://www.acme.com/ACMRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">atypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
#=>   <GetQuote/>
#=> </p:ACMRequest>

@muistooshort No; the first four blocks (quote, code, quote, code) are all from the page. I'll indent them all for increased clarity.

As for the namespace prefix on the root element itself

I cannot figure out how to apply a namespace prefix to the first element in Nokogiri during creation. Instead, you have to apply the namespace after creating the document:

It looked like an editing mistake but it was just a Markdown artifact. You can make a "code block inside a blockquote" work if you use enough leading spaces on the code block and enough > for the blockquote. I think I fixed it, I'm just feeling a bit OCD this morning

Namespaces are added similarly to attributes. Nokogiri::XML::Builder assumes that when an attribute starts with xmlns, it is meant to be a namespace:

Sorry for the late response. @Phrogz thanks for your extensive response. My experience with XML has been rather limited but your response did clear up a few other questions I had as well. I have lost count of how many times I have looked at the Nokogiri documentation but its not till someone else explains it that things makes sense. :-) yup i did notice the typo in the code block too :-)

Note