Ruby XML:为现有的 XML 提供唯一的节点以供读取

发布于 2024-10-07 10:04:24 字数 1010 浏览 2 评论 0原文

这是我的问题。我正在调用一个返回多个包含不同值的相同节点的服务。我需要从这些节点获取 GUID 值,并将它们作为变量存储在我的脚本中以供稍后使用。

我从服务编写的 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,它们是动态的。我不想根据我当前拥有的值使用正则表达式来分割它。这很糟糕,稍后会咬我。此时我唯一感兴趣的是读取此 XML 并拉回每个请求的所有值并将它们放入一个可以在代码中映射的数组中。我的问题是,如果您有这个 XML 块,并且需要将 GUID 和 GUID2 作为变量存储在 Ruby 脚本中,您建议使用什么来解析它,您是否有一个读取它并剥离它的示例价值?

ROXML、REXML、Nokogiri、正则表达式???

感谢您的帮助!
~问候无灵感

Here's my problem. I am calling a service that is returning several identical nodes which contain different values. I need to get the GUID values from these nodes and store them as a variable in my script to use later.

Example of the XML I write from the service:

<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>

I have several of these per request and they are dynamic. I don't want to chop this up using regex based on the values I currently have. That's hacky and will bite me later. The only thing I'm interested in at this point is reading this XML and pulling back all the values per request and putting them into an array which I can map in my code. My question is this, if you had this chunk of XML and you needed to get GUID and GUID2 to be stored as variables in a Ruby script what would you suggest using to parse it and do you have an example of reading it in and stripping the value?

ROXML, REXML, Nokogiri, Regex???

I appreciate your help!
~Regards Uninspired

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怼怹恏 2024-10-14 10:04:24

当然,使用 XML 解析库!我能想到手动执行此操作的唯一原因是避免对 gem 的依赖。至于库,这是非常主观的,但我推荐 Nokogiri:快速、简洁且功能强大。

require 'nokogiri'
doc = Nokogiri::XML.parse(xml_string)
doc.css("ShippingMethod ShippingMethodId").map(&:text) # ["GUID", "GUID2"]

Definitely, use a XML parsing library! the only reason I could think of for doing it manually is to avoid a gem dependency. As for the library, that's very subjective, but I'd recommend Nokogiri: fast, concise and powerful.

require 'nokogiri'
doc = Nokogiri::XML.parse(xml_string)
doc.css("ShippingMethod ShippingMethodId").map(&:text) # ["GUID", "GUID2"]
情场扛把子 2024-10-14 10:04:24

我过去曾成功地使用 REXML 来完成此类任务。以下脚本将提取 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 字符串而不是文件。在 REXML 解析它之前,您必须将 xml 片段包装在单个根元素中,使其成为格式良好的 XML:

<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>

I have used REXML for tasks like this successfully in the past. The following script will extract the GUID values:

require "rexml/document"

doc = REXML::Document.new File.open('doc.xml')
guids = doc.root.get_elements('//ShippingMethodId').map { |element| element.get_text }

assuming a file name 'doc.xml' or you can just pass in the XML string instead of a file. You will have to wrap the xml fragment in a single root element to make it well-formed XML before REXML will parse it:

<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>
很酷不放纵 2024-10-14 10:04:24

我会采取以下一些方法:

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"]

Here's some ways I'd do it:

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"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文