2011-01-30 54 views
4

随着角度来说,Hpricot里面,你可以这样做:使用引入nokogiri对文本节点交换一个DocumentFragment的

> 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吗?

编辑:请注意,这是不是与参数swap一个问题,它是一个与接收器

例如一个问题:

> 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" 
+1

鉴于几乎你的问题100个人捐出自己的空闲时间帮你还没有从你接受标志增光,原谅我,如果我迫不及待地想看到回答如何我来回应在花时间回答这个问题之前,你的另一个问题就变成了现实。 – Phrogz 2011-01-30 05:17:16

+0

我的坏狗;我没有看到你的答案! – 2011-01-30 05:21:19

回答

2

下面是创建一个文本节点的一种方式可与交换可以使用的DocumentFragment内:

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的根,或者如果这是一个文档,而不是片段:

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.