2015-06-19 76 views
0

我这样做:如何添加元素?

​​

然而@xml仍然没有我的目标。我能做些什么来更新原始@xml

+0

Does [this question](http://stackoverflow.com/questions/939853/how-can-i-add-a-child-to-a-node-at-a-specific-position)回答你的问题? – tadman

+0

您确实应该添加与您的代码匹配的示例XML,以及您期望的XML应该如何。不要要求我们凑齐样本数据。 –

回答

1

这是比这更容易了很多:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<root> 
    <node> 
    </node> 
</root> 
EOT 

doc.at('node').children = '<child>foo</child>' 
doc.to_xml 
# => "<?xml version=\"1.0\"?>\n<root>\n <node><child>foo</child></node>\n</root>\n" 

children=是足够聪明,看你传递什么和会做肮脏的工作适合你。所以只需使用一个字符串来定义新节点并告诉Nokogiri在哪里插入它。


doc.at('node').class # => Nokogiri::XML::Element 
doc.at('//node').class # => Nokogiri::XML::Element 

doc.search('node').first # => #<Nokogiri::XML::Element:0x3fd1a88c5c08 name="node" children=[#<Nokogiri::XML::Text:0x3fd1a88eda3c "\n ">]> 
doc.search('//node').first # => #<Nokogiri::XML::Element:0x3fd1a88c5c08 name="node" children=[#<Nokogiri::XML::Text:0x3fd1a88eda3c "\n ">]> 

search是通用的 “找点” 的方法,将采取任何CSS或XPath选择。 at相当于search('some selector').firstat_cssat_xpathat的具体等同物,就像cssxpathsearch。如果你想使用特定的版本,但通常我使用通用版本。


不能使用:

​​

targets[](实际上是一个空节点集),如果./target不会在DOM存在。您不能追加节点到[],因为NodeSet不知道您在说什么,导致undefined method 'children=' for nil:NilClass (NoMethodError)异常。

相反,您必须找到要插入节点的特定位置。 at是很好的,因为它找到了第一个位置。当然,如果你想查找多个地方来修改某些东西,请使用search,然后迭代返回的NodeSet并根据返回的各个节点进行修改。

+0

这是不可能做的xpath?事情是,我在@xml上收到一个,并且可以修改它... –

+0

无论您使用'xpath'或'css'还是'at'或任何的“查找节点”方法。重要的是你如何添加它。 –

+0

我正在选择你的答案,因为你提供了很多有用的信息,但请检查答案,你会发现这样做的缺点吗? –

0

我结束这样做,工作正常。

targets = @xml.xpath("./target") 
if targets.empty? 
    targets << Nokogiri::XML::Node.new('target', @xml) 
    @xml.add_child(targets.first) 
end