我使用rest-client从另一个网站返回XML,并试图使用Nokogiri来解析它。XML看起来像这样:
<?xml version="1.0" encoding="UTF-8"?> ...
<MXAUTOKESet>
<AUTOKEY>
<AUTOKEYID>27</AUTOKEYID>
<AUTOKEYNAME>WORKORDERNUM</AUTOKEYNAME>
<ORGID>xxxx</ORGID>
<PREFIX>12-</PREFIX>
<SEED>38979</SEED>
...
我想提取"PREFIX"one_answers"SEED"数字。
我的视图代码是这样的:
<% xml_data = RestClient.get "URL (sorry can't display it in this question)" %>
<%= xml_doc = Nokogiri::XML(xml_data)%>
第二行显示页面上返回的XML,因此,我知道rest-client正在工作,但我不知道如何访问解析后的XML。
UPDATE1:
我能够使用以下命令从XML头中获得creationDateTime
。但是,我仍然无法获得SEED值:
<%= doc = Nokogiri::XML(xml_data)%>
<h4>Creation Date</h4>
<% root = doc.root %>
<%= root["creationDateTime"] %>
<h4>SEED</h4>
<%= seed = root.xpath("SEED").text %>
或
<%= seed = doc.xpath("//SEED").inner_text %>
你的代码中有一些错误,所以我是这样做的:
从下面的代码开始:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<?xml version="1.0" encoding="UTF-8"?>
<MXAUTOKESet>
<AUTOKEY>
<AUTOKEYID>27</AUTOKEYID>
<AUTOKEYNAME>WORKORDERNUM</AUTOKEYNAME>
<ORGID>xxxx</ORGID>
<PREFIX>12-</PREFIX>
<SEED>38979</SEED>
EOT
puts doc.to_xml
我得到这样的输出,显示Nokogiri做了一些修复来关闭打开的标记,以确保XML块的合理正确:
<?xml version="1.0" encoding="UTF-8"?>
<MXAUTOKESet>
<AUTOKEY>
<AUTOKEYID>27</AUTOKEYID>
<AUTOKEYNAME>WORKORDERNUM</AUTOKEYNAME>
<ORGID>xxxx</ORGID>
<PREFIX>12-</PREFIX>
<SEED>38979</SEED>
</AUTOKEY></MXAUTOKESet>
xpath
需要一个XPath访问器,并返回一个NodeSet,它类似于一个节点数组:
doc.xpath("//SEED").class
=> Nokogiri::XML::NodeSet
doc.xpath("//SEED")
=> [#<Nokogiri::XML::Element:0x3fdf890e3208 name="SEED" children=[#<Nokogiri::XML::Text:0x3fdf890e3000 "38979">]>]
问题是,xpath
及其对应的css
将返回它们在文档中找到的目标的每次出现,如果有两个或更多的"种子",这不是您想要的。标签。相反,您希望at
或at_xpath
或at_css
返回找到的第一个事件;我建议在第一次测试中使用at
(或search
)和CSS,因为它比XPath更容易理解。
转换为使用at
和CSS:
doc.at("SEED").class
=> Nokogiri::XML::Element
doc.at("SEED")
=> #<Nokogiri::XML::Element:0x3fdf890e3208 name="SEED" children=[#<Nokogiri::XML::Text:0x3fdf890e3000 "38979">]>
请注意,doc.at("SEED")
返回了一个"Nokogiri::XML::Element",这是Nokogiri描述节点的方式,而不是xpath
(AKA search
)的NodeSet (AKA Array)。
获取文本很简单,只要你有节点:
doc.at("SEED").text
=> "38979"
以下是我如何获取这两个值并将它们分配给两个变量的方法,给出了这个小XML片段:
seed, prefix = %w[SEED PREFIX].map{ |t| doc.at(t).text }
=> ["38979", "12-"]
您的最后一行代码puts doc.xpath("//SEED").inner_text
应该可以工作。真正的XML有名称空间吗?如果是,请尝试这样做:puts doc.css("SEED").inner_text