RubyXML:为现有XML提供唯一的节点来读取
这是我的问题。我正在调用一个服务,该服务返回几个包含不同值的相同节点。我需要从这些节点获取GUID值,并将它们作为变量存储在脚本中以供以后使用 我从服务中编写的XML示例:RubyXML:为现有XML提供唯一的节点来读取,ruby,xml,xml-parsing,Ruby,Xml,Xml Parsing,这是我的问题。我正在调用一个服务,该服务返回几个包含不同值的相同节点。我需要从这些节点获取GUID值,并将它们作为变量存储在脚本中以供以后使用 我从服务中编写的XML示例: <ShippingMethod> <Description>Description Goes Here</Description> <HandlingCharge>16.98</HandlingCharge> <ShippingMeth
<ShippingMethod>
<Description>Description Goes Here</Description>
<HandlingCharge>16.98</HandlingCharge>
<ShippingMethodId>GUID</ShippingMethodId>
<ShippingMethodName>Express Overnight</ShippingMethodName>
</ShippingMethod>
<ShippingMethod>
<Description>Description2 Goes Here</Description>
<HandlingCharge>19.98</HandlingCharge>
<ShippingMethodId>GUID2</ShippingMethodId>
<ShippingMethodName>More Express Overnight</ShippingMethodName>
</ShippingMethod>
这里有描述
16.98
指南
通宵快递
描述2在这里
19.98
指南2
通宵快递
我在每个请求中都有几个,它们是动态的。我不想基于我目前拥有的值,用正则表达式把它切碎。那是黑的,以后会咬我的。此时,我唯一感兴趣的事情是读取此XML,并提取每个请求的所有值,然后将它们放入一个数组中,我可以在代码中映射该数组。我的问题是,如果您有这段XML,并且需要将GUID和GUID2作为变量存储在Ruby脚本中,您会建议使用什么来解析它?您是否有一个读取它并剥离值的示例
ROXML,REXML,Nokogiri,Regex
我感谢你的帮助~z~我过去曾成功地完成过类似的任务。以下脚本将提取GUID值:
require "rexml/document"
doc = REXML::Document.new File.open('doc.xml')
guids = doc.root.get_elements('//ShippingMethodId').map { |element| element.get_text }
假设文件名为“doc.xml”,或者您可以只传入xml字符串而不是文件。您必须将xml片段包装在单个根元素中,以使其成为格式良好的xml,然后REXML才能对其进行解析:
<Root>
<ShippingMethod>
<Description>Description Goes Here</Description>
<HandlingCharge>16.98</HandlingCharge>
<ShippingMethodId>GUID</ShippingMethodId>
<ShippingMethodName>Express Overnight</ShippingMethodName>
</ShippingMethod>
<ShippingMethod>
<Description>Description2 Goes Here</Description>
<HandlingCharge>19.98</HandlingCharge>
<ShippingMethodId>GUID2</ShippingMethodId>
<ShippingMethodName>More Express Overnight</ShippingMethodName>
</ShippingMethod>
</Root>
这里有描述
16.98
指南
通宵快递
描述2在这里
19.98
指南2
通宵快递
当然,要使用XML解析库!我能想到的手动操作的唯一原因是避免gem依赖。至于图书馆,这是非常主观的,但我推荐Nokogiri:快速、简洁和强大
require 'nokogiri'
doc = Nokogiri::XML.parse(xml_string)
doc.css("ShippingMethod ShippingMethodId").map(&:text) # ["GUID", "GUID2"]
以下是我的一些方法:
require 'nokogiri'
xml = '<xml><ShippingMethod>
<Description>Description Goes Here</Description>
<HandlingCharge>16.98</HandlingCharge>
<ShippingMethodId>GUID</ShippingMethodId>
<ShippingMethodName>Express Overnight</ShippingMethodName>
</ShippingMethod>
<ShippingMethod>
<Description>Description2 Goes Here</Description>
<HandlingCharge>19.98</HandlingCharge>
<ShippingMethodId>GUID2</ShippingMethodId>
<ShippingMethodName>More Express Overnight</ShippingMethodName>
</ShippingMethod></xml>
'
doc = Nokogiri::XML(xml)
doc.css('ShippingMethodId').inject([]){ |m,a| m << a.text } # => ["GUID", "GUID2"]
(doc / '//ShippingMethodId').map{ |n| n.text } # => ["GUID", "GUID2"]
doc.search('//ShippingMethodId').map(&:text) # => ["GUID", "GUID2"]
doc.search('//ShippingMethodId/text()').map{ |n| n.text } # => ["GUID", "GUID2"]
doc.search('//ShippingMethodId/text()').map(&:to_s) # => ["GUID", "GUID2"]
需要“nokogiri”
xml='1〕
这里有描述
16.98
指南
通宵快递
描述2在这里
19.98
指南2
通宵快递
'
doc=Nokogiri::XML(XML)
css('ShippingMethodId').inject([]){m,a | m[“GUID”,“GUID2”]
(doc/'//ShippingMethodId').map{n | n.text}#=>[“GUID”,“GUID2”]
doc.search('//ShippingMethodId').map(&:text)#=>[“GUID”,“GUID2”]
doc.search(“//ShippingMethodId/text()”).map{n|n.text}}}=>[“GUID”,“GUID2”]
doc.search('//ShippingMethodId/text()).map(&:to#s)#=>[“GUID”,“GUID2”]
除非XML完全在您的控制范围内且非常简单,否则不要使用正则表达式。像Nokogiri这样的解析器使用起来非常简单,而且更加健壮。想象一下,如果您的XML从漂亮的打印/缩进格式变为一行中的所有格式,并且您正在使用正则表达式,会发生什么情况。解析器不会在意。为什么在第一个正则表达式中使用inject充足而不是地图?这只是一种不同的实现方式。就像他们说的,“剥猫皮的方法不止一种。”