2013-05-17 3 views
0

Я использую Nokogiri (1.5.9 - java) в JRuby (1.6.7.2), чтобы скопировать шаблон XML и отредактировать его. У меня проблемы с поиском элементов в клонированном документе.Cant find element in clone document

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. Где моя ошибка?

+0

'.// lblock' означает найти lblock под * текущим * узлом. Может быть, у документа 'dup'ed нет текущего узла? Вы пробовали абсолютный XPath вместо относительного? –

ответ

0

Я не могу дублировать проблему:

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 работают с XPaths и CSS соответственно. at попытается выяснить, является ли строка CSS или XPath, и, как правило, это правильно, хотя я видел, как она обманула.

lblock.children = new_children 

В этом случае new_children является строка. Nokogiri достаточно умен, чтобы знать, что перед его использованием он должен преобразовать строку в фрагмент XML. Это упрощает изменение XML или HTML-документов со строками вместо создания DocumentFragments.