问题描述
我试图在xml文件中为一个特定的元素设置一个属性,我使用
I was trying to set an attribute for a specific element in an xml file and I was having success using
doc.css('Object').attr("Id").value = timestamp
对象不存在导致程序中的异常并退出的情况。为了避免我想使用Nodeset,因为它只是空的。
This was fine until the situation where 'Object' doesn't exist causing an exception in the program and quitting. To avoid that I wanted to use Nodeset as it'll just be empty instead.
doc.css('Object').each do |element|
element.attr("Id").value = timestamp
end
但是,这返回一个错误,值=是一个未定义的方法。这可能是简单的,但我是新的Ruby和CSS所以任何帮助将是伟大的。
However this returns with the error that value= is an undefined method. It's probably something simple but I'm new to Ruby and CSS so any help would be great.
推荐答案
这个问题与CSS无关,因为Nokogiri使用CSS选择器来替代使用XPath选择器,只用于提供到一个节点或节点的路径。
The problem has little to do with CSS, since Nokogiri uses CSS selectors as an alternative to using XPath selectors, and both are only used to provide a path to a node, or nodes.
看起来你正在考虑这个问题,并使它比它需要的更难。这是我要做的:
It looks like you're overthinking this, and making it harder than it needs to be. Here's what I'd do:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<xml>
<foo>
<Object>bar</Object>
</foo>
</xml>
EOT
doc.at('Object')["Id"] = Time.now.to_s
查看 doc
此时显示:
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <xml>
# >> <foo>
# >> <Object Id="2014-01-28 19:13:32 -0700">bar</Object>
# >> </foo>
# >> </xml>
了解,和,它返回第一个匹配的和,和,它们返回NodeSets。 类似于包含节点的数组。当你知道,你的声明:
It's really important to understand the difference between at
, at_css
and at_xpath
, which return the first matching Node, and search
, css
and xpath
, which return NodeSets. A NodeSet is akin to an array containing Nodes. When you know that, your statement:
doc.css('Object').attr("Id").value = timestamp
没有什么意义,特别是因为这不是方法定义: p>
won't make much sense, especially since that's not how the attr
method is defined:
attr(key, value = nil, &blk)
您需要使用:
doc.css('Object').attr("Id", value)
< Object>
节点的所有 Id
属性
which would assign value
to all Id
attributes for every <Object>
node in the document.
但是,再次,这不是正确的选择,而应该使用在
或 at_css
返回单个节点。
But, again, that's not the right choice, instead you should use at
or at_css
to return the single node.
如果没有< Object>
节点存在, ,你必须决定做什么。
If no <Object>
node exists, then it gets more interesting, and you have to determine what to do. You can insert it, or, you can simply move along and do nothing.
要查看节点是否存在很简单:
To see if a node exists is simple:
object_node = doc.at('Object')
if object_node
object_node['Id'] = Time.now.to_s
else
# ... insert it
end
找到要插入它的位置,然后添加它:
To insert a node involves locating the place you want to insert it, then add it:
doc.at('foo').add_child("<Object Id='#{ Time.now }'>baz</Object>")
puts doc.to_xml
# >> <?xml version="1.0"?>
# >> <xml>
# >> <foo>
# >> <Object>bar</Object>
# >> <Object Id="2014-01-28 19:39:38 -0700">baz</Object></foo>
# >> </xml>
我没有尝试使XML输出漂亮,这在XML中并不重要,
I didn't try to make the XML output pretty, which isn't important in XML, it merely needs to be syntactically correct.
还要注意,可以通过将一个节点或多个节点定义为一个XML字符串来插入这些节点。 Nokogiri会把它解析成合适的XML并移植到你说的地方。你也可以通过定义一个NodeSet或Node,然后插入它,走长路由,但是,一般来说,这使得更丑陋的代码,并导致你做更多的工作,这导致较少可读的代码为那些跟随你的脚步保持源。
Also note that it's possible to insert a node, or nodes, by defining them as a string of XML. Nokogiri will parse it into the appropriate XML and graft it in where you said. You could also go the long route by define a NodeSet or Node, then inserting it, but, in general, that makes uglier code and causes you to do a lot more work, which results in less readable code for those who follow in your footsteps maintaining the source.
这篇关于使用css在Nokogiri :: XML :: NodeSet中设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!