NodeSet中设置属性

NodeSet中设置属性

本文介绍了使用css在Nokogiri :: XML :: NodeSet中设置属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在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中设置属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 02:38