0

我正在使用 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”和“SEED”数字。

我的视图代码如下所示:

<% xml_data = RestClient.get "URL (sorry can't display it in this question)" %>
<%= xml_doc  = Nokogiri::XML(xml_data)%>

第二行在页面上显示返回的 XML,因此,我知道 rest-client 正在工作,但我不知道如何访问已解析的 XML。


更新1:

我能够creationDateTime使用以下方法摆脱 XML 标头。但是,我仍然无法获得 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 %>
4

2 回答 2

2

您的代码中有几处错误,所以这就是我的处理方式:

从此代码开始:

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对应物将返回他们在文档中找到的每个目标,如果有两个或更多“SEED”标签,这不是您想要的。相反,您希望ator at_xpathor at_csswhich 返回找到的第一个匹配项;我建议在您的第一次测试中使用at(or 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 ) 的 NodeSet (AKA Array search)。

拥有节点后,获取文本很简单:

doc.at("SEED").text
=> "38979"

下面是我如何获取两个值并将它们分配给两个变量,给定小的 XML 片段:

seed, prefix = %w[SEED PREFIX].map{ |t| doc.at(t).text }
=> ["38979", "12-"]
于 2013-02-27T06:14:55.167 回答
1

您的最后一行代码puts doc.xpath("//SEED").inner_text, 应该可以工作。真正的 XML 是否有任何名称空间?如果是这样,请尝试以下操作:puts doc.css("SEED").inner_text

于 2013-02-27T02:07:03.027 回答