如何使用Nokogiri在NodeSet中添加子节点

我试图在根节点下添加子节点..我尝试使用下面的xml,但这不起作用。 我是Ruby和Nokogiri的新手

builder = Nokogiri::XML::Builder.with(@doc) do |xml| nodes = Nokogiri::XML::NodeSet.new(@doc, []) [].each {|nodes_one_by_one| << nodes_one_by_one.Book << nodes_one_by_one.Pen } end 

我需要像这样在根节点下面添加节点

  abc Benjamin 

这对我有用..但我真正需要的是在文档中的特定位置之后添加这些节点。

  <!-- abc Benjamin -->     

我尝试使用at_xpath(’// Catlog’),但它在元素的末尾添加(如你所说)

      <!-- abc Benjamin --> 

 book = Nokogiri::XML::Node.new('book', doc) pen = Nokogiri::XML::Node.new('pen', doc) . . 

无论如何使用“each”循环而不是逐个添加..我试过这种方式,但这不起作用。

builder = Nokogiri :: XML :: Builder.with(doc)do | xml |
nodes = Nokogiri :: XML :: Node.new(doc,[])
[] .each {| child_list_element |
child_list_element.Book“value”child_list_element.Pen“value”child_list_element.Diary“value”child_list_element.Pen_stand“value”child_list_element.Pencil“value”。 。 。
}
结束
doc <<节点

代码可能是错误的,但我想这样做。 还有一个就是..我可以将所有元素添加为NodeSet而不是Node。 请更正我的代码。

提前致谢


  1. 嵌套的OpenStruct似乎没有正常工作。 我尝试了下面的例子

    商店目录集

     require 'ostruct' require 'nokogiri' collection = [ OpenStruct.new(:catalogStoreNumber => '657758', :catalogStoreId => 'CTH6536', :catalogStoreLocation => 'UnitedStates', :catalogOwnerId => 'TYCT11190', :catalogOwner => 'McGrawHill Pub.', :catalogList => OpenStruct.new( :catalogProductInfo => OpenStruct.new( :productType => 'Book', :productName => 'The Client', :productId => 'CRSUS113246A', :productCategory => 'Crime And Suspense', :productSubcategory => 'Vintage Books', :productPrice => '45.50 USD', :productAuthor => OpenStruct.new( :authorFirstName =>'John Grisham', :authorMiddleName=> 'Willburt', :authorContact => '19876648981')), :catalogProductInfo => OpenStruct.new( :productType => 'Pen', :productName => 'Reynolds', :productId => 'PRREY546647', :productCategory => 'Misc. Stationary', :productSubcategory => 'Stationery Items', :productPrice => '3.00 USD', :productManufacturer => 'Reynolds Inc.', :productAuthor => OpenStruct.new( :authorFirstName => 'Ryan Reynolds', :authorMiddleName => 'William', :authorContact => '16577589898')), :catalogListType => 'ProductCollection', :catalogListSource => 'Web' ), :catalogVerificaitionLog => OpenStruct.new( :catalogVerificationStatus => 'Verified', :catalogVerificationDateTime => '2012-03-12T13:00:15+5:30', :catalogVerificationId => '64774A', :catalogVerificationRequestedBy => 'user_121') )] 

我想访问第一个“catalogProductInfo”的“productType”,我说“collection.catalogList.catalogProductInfo.productType.content”,我得到以下错误

“未定义的方法`productType’用于#(NoMethodError)

OpenStruct是否支持嵌套OpenStruct我想使用OpenStruct和Nokogiri以下面的格式构建XML?

  657758 CTH6536 UnitedStates TYCT11190 McGrawHill Pub.   Book The Client CRSUS113246A Crime And Suspense Vintage Books 45.50 USD  John Grisham Willbur 19876648981    Pen Reynolds PRREY546647 Misc. Stationary Stationary Items 3.00 USD  Ryan Reynolds William 16577589898   ProductCollection Web   Verified 2012-03-12T13:00:15+5:30 64774A User_121  

我想使用Nokogiri和OpenStruct实现这一点,但我不确定它是否可以使用OpenStruct,因为它缺乏嵌套function。 有没有其他方法可以使用JSon实现这一点而没有任何明显的限制? 请更正我之前的代码。

如果我正确理解你,以下应该大致是你正在寻找的:

 doc = Nokogiri::XML(original_xml_string) catalog = doc.at_css('Catalog') # #at_css will just grab the first node. # use #css if you want to loop through several. # alternatively just use doc.root book = Nokogiri::XML::Node.new('Book', doc) book_author = Nokogiri::XML::Node.new('Book_Author', doc) book.content = 'abc' book_author.content = 'benjamin' catalog << book catalog << book_author 

<<应该在元素结束之前附加节点。

更新

在更新了问题并简化了@ Phrogz的建议之后,这应该符合您的要求:

 require 'nokogiri' xml = <<'XML'      XML doc = Nokogiri::XML(xml) catalog = doc.root catalog.first_element_child.before("abc") catalog.first_element_child.before("benjamin") puts doc.to_xml 

更新2

要迭代集合,动态添加节点,并使用NodeSet,请尝试以下操作:

 require 'nokogiri' require 'ostruct' xml = <<-'XML'      XML collection = [ OpenStruct.new(book: '1984', pen: 'George Orwell'), OpenStruct.new(book: 'Thinking, Fash and Slow', pen: 'Daniel Kahneman') ] doc = Nokogiri::XML(xml) catalog = doc.root node_set = Nokogiri::XML::NodeSet.new(doc) collection.each do |object| book = Nokogiri::XML::Node.new('Book', doc) book_author = Nokogiri::XML::Node.new('Book_Author', doc) book.content = object.book book_author.content = object.pen node_set << book node_set << book_author end catalog.first_element_child.before(node_set) puts doc.to_xml