Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何在Nokogiri中收集节点的几个元素中的第一个元素_Ruby_Xml_Nokogiri - Fatal编程技术网

Ruby 如何在Nokogiri中收集节点的几个元素中的第一个元素

Ruby 如何在Nokogiri中收集节点的几个元素中的第一个元素,ruby,xml,nokogiri,Ruby,Xml,Nokogiri,我有如下数据: <release> <artists> <artist> <name>Johnny Mnemonic</name> </artist> <artist> <name>Constantine</name> </artist> <artists> </release> <release> &l

我有如下数据:

<release> 
 <artists>
  <artist>
   <name>Johnny Mnemonic</name>
  </artist>
  <artist>
    <name>Constantine</name>
  </artist>
 <artists>
</release>
<release>
 <artists>
  <artist>
   <name>Speed</name>
  </artist>
  <artist>
    <name>The Matrix</name>
  </artist>
 <artists>
 </release>
 ...and so on.

xpath表达式选择的是
,而不是像预期的那样选择每个
标记。请尝试以下操作:

doc.search('artists artist').map(&:text)

您的表达式
“//artists”
将检索所有的“artists”标记,
[1]
选择这些标记中的第一个,而不是标记本身内部的第一个元素。

Nokogiri支持两种主要的搜索类型,
搜索
at
<代码>搜索返回一个节点集,您应该将其视为一个数组
at
返回一个节点。可以采用CSS或XPath表达式。我更喜欢CSS,因为它们更具可读性,但有时你不能很容易地找到你想要的位置,所以试试另一个

对于您的问题,使用
text
指定要从中提取文本的节点非常重要。如果结果太宽,除了所需标记内的文本外,还将从标记之间获得文本。要避免深入到最直接的节点以了解您要读取的内容,请执行以下操作:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<release> 
<artists>
  <artist>
  <name>Johnny Mnemonic</name>
  </artist>
  <artist>
    <name>Constantine</name>
  </artist>
<artists>
<release>
EOT
这些搜索比较松散,因此会返回更多垃圾邮件:

doc.at('artist').text  # => "\n   Johnny Mnemonic\n  "
doc.at('artists').text # => "\n  \n   Johnny Mnemonic\n  \n  \n    Constantine\n  \n \n\n"
使用
search
返回多个节点:

doc.search('name').map(&:text)

[
    [0] "Johnny Mnemonic",
    [1] "Constantine"
]

doc.search('artist').map(&:text)

[
    [0] "\n   Johnny Mnemonic\n  ",
    [1] "\n    Constantine\n  "
]
search
at
之间唯一的真正区别是
at
就像
search(…)。首先

另见“”一节

为了方便起见,Nokogiri还有一些额外的别名:
at_css
css
,以及
at_xpath
xpath


以下是从Pry截取的使用CSS和XPath访问器获取名称的替代方法:

[5] (pry) main: 0> # using CSS with Ruby
[6] (pry) main: 0> artists = doc.search('release').map{ |release| release.at('artist').text.strip }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[7] (pry) main: 0> # using CSS with less Ruby
[8] (pry) main: 0> artists = doc.search('release artists artist:nth-child(1) name').map{ |n| n.text }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[9] (pry) main: 0>
[10] (pry) main: 0> # using XPath
[11] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name').map{ |t| t.content }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[12] (pry) main: 0> # using more XPath
[13] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name/text()').map{ |t| t.content }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]

page.xpath(“release/artists/artist”)。首先
?非常感谢。我想要的似乎是医生的名字。还有一个问题,你能告诉我如何在每个节点上重复吗?啊。你没有给我们一个准确的数据例子<代码>“名称”不考虑任何包含的节点。
是否重要,导致您中断并为每个人做一些特殊的事情?根据我给你的信息,你应该能找到答案。对不起。Release是第一个节点,其余节点都作为子节点。我想从每个版本中提取第一个“名称”数据,其中可能有10000个。因此,您的代码从第一个发行版节点中提取了第一个名称,我希望在每个版本中重复该操作,并且以与第一个版本相同的方式进行结构。同样,您的示例数据需要显示这一点。请加一个准确的例子。减少它,但它需要显示您将使用什么。对代码的修复很容易,但我想做一次更改,而不是在源数据显示出更多更改时一次又一次地进行更改。抱歉,代码已编辑。这是两个版本的示例,其中将有数千个版本。我想从每个节点提取第一个“名称”数据。
doc.search('name').map(&:text)

[
    [0] "Johnny Mnemonic",
    [1] "Constantine"
]

doc.search('artist').map(&:text)

[
    [0] "\n   Johnny Mnemonic\n  ",
    [1] "\n    Constantine\n  "
]
[5] (pry) main: 0> # using CSS with Ruby
[6] (pry) main: 0> artists = doc.search('release').map{ |release| release.at('artist').text.strip }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[7] (pry) main: 0> # using CSS with less Ruby
[8] (pry) main: 0> artists = doc.search('release artists artist:nth-child(1) name').map{ |n| n.text }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[9] (pry) main: 0>
[10] (pry) main: 0> # using XPath
[11] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name').map{ |t| t.content }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]
[12] (pry) main: 0> # using more XPath
[13] (pry) main: 0> artists = doc.search('release/artists/artist[1]/name/text()').map{ |t| t.content }
[
    [0] "Johnny Mnemonic",
    [1] "Speed"
]