該問題與CSS無關,因爲Nokogiri使用CSS選擇器作爲使用XPath選擇器的替代方法,並且兩者僅用於提供節點或節點的路徑。
它看起來像你正在反思這一點,並使它比需要更難。這裏就是我想要做的:
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>
瞭解at
,at_css
和at_xpath
之間的區別是非常重要的,它會返回第一個匹配的Node,和search
,css
和xpath
,其返回NodeSets。 A NodeSet類似於包含節點的數組。當你知道,你的發言:
doc.css('Object').attr("Id").value = timestamp
將沒有多大意義,尤其是因爲這不是如何attr
方法定義:
attr(key, value = nil, &blk)
你需要使用:
doc.css('Object').attr("Id", value)
它將爲文檔中的每個<Object>
節點的所有Id
屬性分配value
屬性。
但是,這不是正確的選擇,而應該使用at
或at_css
來返回單個節點。
這是罰款,直至情況下如果沒有<Object>
節點存在「對象」不存在
,那麼它變得更有趣,你要確定該怎麼做。你可以插入它,或者,你可以簡單地移動,不做任何事情。
要查看某個節點存在簡單:
object_node = doc.at('Object')
if object_node
object_node['Id'] = Time.now.to_s
else
# ... insert it
end
要插入一個節點包括定位要插入的地方,然後將其添加:
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中不重要,它只需要在語法上是正確的。
另請注意,可以通過將節點或節點定義爲XML字符串來插入節點。 Nokogiri會將其解析爲適當的XML並將其移植到您所說的地方。你也可以通過定義一個NodeSet或者Node,然後插入它來走長路,但是,一般來說,這會產生更醜陋的代碼,並導致你做更多的工作,這會導致那些跟隨你腳步的人的可讀代碼變少維護來源。
感謝您的詳細回覆!這肯定有幫助。我一直在思考,並讓我的程序工作,我想要它! – Jud202
很高興幫助。在Perl中使用XML解析器之後,我來到了Ruby和Nokogiri,並且以困難的方式做了很多事情。 Ruby和Nokogiri,使它變得更容易。 –