使用Hpricot,您可以这样做:
> doc = Hpricot("a")
=> #<Hpricot::Doc "a">
> doc.children.first.swap('b')
=> ["b"]
> doc.to_s
=> "b"
但如果你和Nokogiri尝试同样的事情,你会收到一个错误:
> doc = Nokogiri::HTML::DocumentFragment.parse('a')
=> #<Nokogiri::HTML::DocumentFragment:0x825bb88c name="#document-fragment" children=[#<Nokogiri::XML::Text:0x825bb580 "a">]>
> doc.children.first.swap('b')
RuntimeError: error parsing fragment (1)
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:509:in `in_context'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:509:in `parse'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/html/document_fragment.rb:22:in `initialize'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:485:in `new'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:485:in `fragment'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:885:in `coerce'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:382:in `replace'
from /Library/Ruby/Gems/1.8/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:407:in `swap'
from (irb):63
如何在Nokogiri的文本节点上使用swap?
编辑:请注意,这不是ARGUMENT交换的问题,这是接收器的问题
例如:
> doc = Nokogiri::HTML::DocumentFragment.parse('<a>b</a>')
=> #<Nokogiri::HTML::DocumentFragment:0x825bb508 name="#document-fragment" children=[#<Nokogiri::XML::Element:0x825bb1fc name="a" children=[#<Nokogiri::XML::Text:0x825bab6c "b">]>]>
> doc.at("a").swap('x')
=> #<Nokogiri::XML::Element:0x825bb1fc name="a" children=[#<Nokogiri::XML::Text:0x825bab6c "b">]>
> doc.to_s
=> "x"
最佳答案 这是创建可与DocumentFragment中的swap一起使用的文本节点的一种方法:
require 'nokogiri'
frag = Nokogiri::HTML::DocumentFragment.parse( "foo" )
foo = frag.children.first
foo.swap( Nokogiri::XML::Text.new( "bar", foo.document ) )
puts frag
#=> bar
编辑:基于以下内容,这里肯定有一些微妙的变化.我已经为你提交了bug report.如果文本不在DocumentFragment的根目录下,或者如果这是Document而不是片段,它似乎正确解析字符串:
require 'nokogiri'
elems = "<a1 /><a2>foo</a2><a3 /><a4>bar</a4>baz"
rooted = "<r>#{elems}</r>"
doc = Nokogiri::XML rooted
doc.at_xpath('/r/a1').swap( 'x1' ) # Element->text
doc.at_xpath('/r/a2/text()').swap( 'jim' ) # Text->text
doc.at_xpath('/r/a3').swap( '<x3 />' ) # Element->element
doc.at_xpath('/r/a4/text()').swap( '<x4>jam</x4>' ) # Text->element
doc.xpath('/r/text()').last.swap( 'jom' ) # RootText->text
puts doc.root
#=> <r>x1<a2>jim</a2><x3/><a4><x4>jam</x4></a4>jom</r>
#=> (correct output)
frag = Nokogiri::XML::DocumentFragment.parse rooted
frag.at_xpath('./r/a1').swap( 'x1' ) # Element->text
frag.at_xpath('./r/a2/text()').swap( 'jim' ) # Text->text
frag.at_xpath('./r/a3').swap( '<x3 />' ) # Element->element
frag.at_xpath('./r/a4/text()').swap( '<x4>jam</x4>' ) # Text->element
frag.xpath('./r/text()').last.swap( 'jom' ) # RootText->text
puts frag
#=> <r>x1<a2>jim</a2><x3/><a4><x4>jam</x4></a4>jom</r>
#=> (correct output)
frag = Nokogiri::XML::DocumentFragment.parse elems
frag.at_xpath('./a1').swap( 'x1' ) # Element->text
frag.at_xpath('./a2/text()').swap( 'jim' ) # Text->text
frag.at_xpath('./a3').swap( '<x3 />' ) # Element->element
frag.at_xpath('./a4/text()').swap( '<x4>jam</x4>' ) # Text->element
baz = frag.children.last
begin
baz.swap( 'jom' ) # RootText->text
rescue Exception => e
p baz
#=> #<Nokogiri::XML::Text:0x80c66224 "baz">
p e
#=> #<RuntimeError: error parsing fragment (1)>
puts e.backtrace
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:509:in `in_context'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:509:in `parse'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/document_fragment.rb:14:in `initialize'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:485:in `new'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:485:in `fragment'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:885:in `coerce'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:382:in `replace'
#=> /usr/local/lib/ruby/gems/1.9.1/gems/nokogiri-1.4.4/lib/nokogiri/xml/node.rb:407:in `swap'
#=> /Users/phrogz/Desktop/test_swap.rb:32:in `<main>'
end
puts frag
#=> x1<a2>jim</a2><x3/><a4>
#=> <x4>jam</x4>
#=> </a4>baz
编辑2:这已被Nokogiri开发团队确认为错误:
OMG! Thanks for the boog report!
I’m sure we don’t have any test coverage that runs Node#replace and #swap on text nodes, so hopefully I’ll be able to fix this for the 1.4.5 release.