使用Nokogiri的XML Builder添加命名空间

我一直在破坏我的头几个小时,但我似乎无法确定如何在使用Nokogiri XML Builder类构建XML结构时添加XMLNS名称空间。

例如,考虑下面的XML示例:我可以在GetQuote标记之间创建所有内容,但创建“p:ACMRequest”仍然是一个谜。

我遇到了这个参考资料, https://gist.github.com/428455/7a15f84cc08c05b73fcec2af49947d458ae3b96a ,这对我来说仍然没有意义。 即使参考XML文档,http://www.w3.org/TR/xml-names/,也没有多大意义。

 

... ... ... ...

... ...

如果您使用谷歌“nokogiri xml builder命名空间”,那么第一个打击的是Nokogiri文档页面 ,其中说:

命名空间的添加方式与属性类似。 Nokogiri::XML::Builder假定当属性以“xmlns”开头时,它应该是一个命名空间:

  builder = Nokogiri::XML::Builder.new { |xml| xml.root('xmlns' => 'default', 'xmlns:foo' => 'bar') do xml.tenderlove end } puts builder.to_xml 

将输出这样的XML:

      

将此问题应用于您的具体问题,只需:

 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 #=>  #=>  #=>  #=>  

至于根元素本身的名称空间前缀……

  

…我无法弄清楚如何在创建过程中将名称空间前缀应用于Nokogiri中的第一个元素。 相反,您必须在创建文档后应用命名空间:

 root = builder.doc.root acme = root.namespace_definitions.find{ |ns| ns.href==NS["xmlns:p"] } root.namespace = acme puts builder.to_xml #=>  #=> atypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> #=>  #=>  

或者,你可以作弊:

 # This happens to work for now, but I doubt you should rely upon it. builder.doc.root.name = "p:ACMRequest" 

根据“ 使用Nokogiri构建器创建具有命名空间根元素的XML文档 ”,您可以在创建期间通过小型hack执行此操作:

 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['p'].ACMRequest(NS) do xml.GetQuote end } puts builder.to_xml 

生产:

     

这在构建器API中有记录: http : //nokogiri.org/Nokogiri/XML/Builder.html :

引用声明的名称空间

可以使用Nokogiri :: XML :: Builder#[]方法构建引用非默认命名空间(即标记“foo:bar”)的标记。