2015-10-16 3 views
1

Я использую Nokogiri, чтобы изменить содержимое файла XML:Изменение документа XML с Nokogiri

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
    <Default Extension="png" ContentType="image/png"/> 
... 
</Types> 

Мне нужно добавить Default детей Types следующим образом:

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
    <Default Extension="png" ContentType="image/png"/> 
    <Default Extension="jpg" ContentType="image/jpeg"/> 
... 
</Types> 

Я попробовал:

child_node = Nokogiri::XML::Node.new "Default", @doc 
@doc.xpath('//Types/Default').first.add_next_sibling(child_node) 


#but @doc.xpath('//Types/Default').first #=> nil 

Как добавить дочерний узел к Types?

ответ

0

Использование запроса XPath против XML с пространством имен по умолчанию неоднократно задавалось здесь в StackOverflow. На самом деле, я только что отправил answer на вопрос C# по той же теме пару часов назад.

Я не знаю, в частности, Ruby, но обычно для выбора элемента в пространстве имен по умолчанию с использованием XPath вам необходимо сопоставить префикс с URI по умолчанию и использовать этот префикс в XPath, например:

child_node = Nokogiri::XML::Node.new "Default", @doc 
result = @doc.xpath('/d:Types/d:Default', 'd' => 'http://schemas.openxmlformats.org/package/2006/content-types').first 
+1

Большое спасибо, это сработало!
result = @ doc.xpath ('/ d: Типы/d: По умолчанию', 'd' => 'http://schemas.openxmlformats.org/package/2006/content-types').first –

+0

Это не необходимо поблагодарить нас за изменения. Мы делаем это, потому что это улучшает сайт. –

2

Это очень легко изменить узлы с помощью Nokogiri:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
</Types> 
EOT 

types = doc.at('Types') 
types.children = '<Default Extension="png" ContentType="image/png"/><Default Extension="jpg" ContentType="image/jpeg"/>' 

puts doc.to_xml 

# >> <?xml version="1.0"?> 
# >> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
# >> <Default Extension="png" ContentType="image/png"/> 
# >> <Default Extension="jpg" ContentType="image/jpeg"/> 
# >> </Types> 

Другой способ может быть:

types = doc.at('Types') 
[ 
    '<Default Extension="png" ContentType="image/png"/>', 
    '<Default Extension="jpg" ContentType="image/jpeg"/>' 
].each do |node| 
    types.add_child(Nokogiri::XML::Node.new(node, doc)) 
end 

puts doc.to_xml 

# >> <?xml version="1.0"?> 
# >> <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> 
# >> <<Default Extension="png" ContentType="image/png"/>/><<Default Extension="jpg" ContentType="image/jpeg"/>/></Types> 

Обратите внимание, что Nokogiri рада принудить тег в форме строки в узел и добавить его. Это может сделать жизнь намного легче, если вы имеете дело с шаблоном, который хотите вставить.

Смежные вопросы