我在JRuby(1.6.7.2)中使用Nokogiri (1.5.9 - java)复制XML模板并编辑它。我在克隆文档中查找元素时遇到问题。
lblock = doc.xpath(".//lblock[@blockName='WINDOW_LIST']").first
lblock.children = new_children # kind of NodeSet or Node
copy_doc = doc.dup( 1 ) # or dup(0)
lblock = copy_doc.xpath(".//lblock[@blockName='WINDOW_LIST']").first # nil
当打印to_s
或to_xml
时,则lblock
与new_children
同时存在。我错在哪里?
我不能重复这个问题:
require 'nokogiri'
new_children = Nokogiri::XML::DocumentFragment.parse('<foo>bar</foo>')
doc = Nokogiri::XML(<<EOF)
<xml>
<lblock blockName="WINDOW_LIST" />
</xml>
EOF
lblock = doc.xpath(".//lblock[@blockName='WINDOW_LIST']").first
lblock.children = new_children # kind of NodeSet or Node
copy_doc = doc.dup(1) # or dup(0)
lblock = copy_doc.xpath(".//lblock[@blockName='WINDOW_LIST']").first # nil
puts lblock.to_xml
puts
puts doc.to_xml
运行输出:
<lblock blockName="WINDOW_LIST">
<foo>bar</foo>
</lblock>
<?xml version="1.0"?>
<xml>
<lblock blockName="WINDOW_LIST"><foo>bar</foo></lblock>
</xml>
也就是说,这里的代码经过了清理,向您展示了一些更简单的编写方法:
require 'nokogiri'
new_children = '<foo>bar</foo>'
doc = Nokogiri::XML(<<EOF)
<xml>
<lblock blockName="WINDOW_LIST" />
</xml>
EOF
lblock = doc.at_xpath('//lblock')
lblock.children = new_children
copy_doc = doc.dup(1)
lblock = copy_doc.at_css('lblock')
puts lblock.to_xml
puts
puts doc.to_xml
运行后也输出:
<lblock blockName="WINDOW_LIST">
<foo>bar</foo>
</lblock>
<?xml version="1.0"?>
<xml>
<lblock blockName="WINDOW_LIST"><foo>bar</foo></lblock>
</xml>
解析代码:
lblock = doc.at_xpath('//lblock')
lblock = copy_doc.at_css('lblock')
它们使用两种不同的方法来查找相同的东西。在本例中,因为样例XML很简单,所以我使用at
,它返回第一个匹配节点。at_xpath
和at_css
分别使用xpath和CSS。at
将尝试找出字符串是CSS还是XPath,并且通常会正确,尽管我见过它被愚弄。
lblock.children = new_children
在本例中,new_children
是一个String。Nokogiri非常聪明,知道应该在使用字符串之前将其转换为XML片段。这使得使用字符串修改XML或HTML文档变得非常容易,而不必创建DocumentFragments。