【问题标题】:Simple XML parsing example for NokogiriNokogiri 的简单 XML 解析示例
【发布时间】:2014-12-13 00:42:41
【问题描述】:

我正在尝试获取 Response 对象的键和值列表,以便将它们转换为哈希,但我在理解 Nokogiri 时遇到问题。 XML:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
<Response>
    <Name>Anonymous</Name>
    <ExternalDataReference></ExternalDataReference>
    <EmailAddress>hi guys</EmailAddress>
    <IPAddress>blahblah</IPAddress>
    <Status>0</Status>
..... (approximately 30 more elements within each response tag)
</Response>
(approximately 75 more response tags in the document)

我的目标是为每个响应获得类似的东西:

Name: Anonymous
ExternalDataReference:
EmailAddress: hi guys
IPAddress: blahblah

到目前为止我的代码:

f=File.open("./stufftoparse.xml")
doc = Nokogiri::XML(f)
puts "#{doc.xpath("//Response").keys} \n#{doc.xpath("//Response").values}"

我知道上面的代码不起作用,但我不太明白如何获取 Response 标记中的元素(我不认为它们是 Response 的属性,因为它们在自己的 XML 中)。有人可以解释如何做到这一点吗?请注意,我花了一些时间阅读 Nokogiri 文档,但找不到与 XPATH 示例相关的内容。

其他问题: 如何将响应分开,以便我有这样的东西?

Response1:
Name: Anonymous
ExternalDataReference:
EmailAddress: hi guys
IPAddress: blahblah

Response2:
Name: Anonymous
ExternalDataReference:
EmailAddress: hi guys
IPAddress: blahblah

【问题讨论】:

    标签: ruby nokogiri


    【解决方案1】:

    如果您分步尝试,解决方案会更容易看到。

    示例 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <xml>
      <foo>
        <goo>a</goo>
        <hoo>b</hoo>
      </foo>
      <foo>
        <goo>c</goo>
        <hoo>d</hoo>
      </foo>
    </xml>
    

    语法//foo 选择所有foo 元素。

    > puts doc.xpath("//foo")
    <foo>
      <goo>a</goo>
      <hoo>b</hoo>
    </foo>
    <foo>
      <goo>c</goo>
      <hoo>d</hoo>
    </foo>
    

    Nokogiri 以 NodeSet 的形式返回节点,如下所示:

    > puts doc.xpath("//foo").class
    Nokogiri::XML::NodeSet
    

    NodeSet 是可枚举的;可以使用each、map等方法

    > puts doc.xpath("//foo").kind_of?(Enumerable)
    true
    

    这个NodeSet 包含两个foo 元素:

    > doc.xpath("//foo").each{|e| puts e.class }
    Nokogiri::XML::Element
    Nokogiri::XML::Element
    

    语法//foo/* 选择foo 元素的子元素:

    > puts doc.xpath("//foo/*")
    <goo>a</goo>
    <hoo>b</hoo>
    <goo>c</goo>
    <hoo>d</hoo>
    

    要打印元素的信息,请参阅Nokogiri/XML/Node 文档;您可能需要的两种方法是name 和text。

    为您解决方案:

    > doc.xpath("//foo/*").each{|e|
      puts "#{e.name}:#{e.text}" 
    }
    goo:a
    hoo:b
    goo:c
    hoo:d
    

    对于第二个问题,您实际上是在问:

    1. 对于每个foo 元素,获取其子元素
    2. 为每个子元素打印名称和文本

    为您解决方案:

    > doc.xpath("//foo").each_with_index{|parent_elem, parent_count| 
      puts "Parent #{parent_count + 1}"
      parent_elem.elements.each{|child_elem|
        puts "#{child_elem.name}:#{child_elem.text}"
      }
    }
    

    【讨论】:

    • 谢谢,这正是我想要的!
    • 查看您的示例,我试图弄清楚如何将 Response 彼此分开,但通配符似乎可以获取所有孩子,无论它们是否位于不同的 Response 标签中。有没有办法一次只得到一个响应?也许像获取“//Response”然后使用“//Response/*”循环返回以仅获取单个响应的元素?
    • @Rilcon42 将您正在尝试做的事情添加到您的原始问题中,这样我就可以理解您想要的输出,我会在答案中添加更多内容。
    • 我更新了这个问题,非常感谢您抽出宝贵时间查看此问题。
    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    相关资源
    最近更新 更多