# > doc.children.first.swap('b') => ["b"] > doc.to_s => "-6ren">
gpt4 book ai didi

ruby - 在 DocumentFragment 内的文本节点上使用 Nokogiri 的交换

转载 作者:数据小太阳 更新时间:2023-10-29 07:37:03 27 4
gpt4 key购买 nike

使用 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 to 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"

最佳答案

这是创建文本节点的一种方法,该文本节点可与 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.

关于ruby - 在 DocumentFragment 内的文本节点上使用 Nokogiri 的交换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4841289/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com