Ruby REXML如何获取模式中的第一个同级

Ruby REXML如何获取模式中的第一个同级,ruby,xml,rexml,Ruby,Xml,Rexml,我试图解析MLB GameDay中可用的信息。下面是我正在使用的一个示例文件: 具体来说,下面是一个XML输出示例: <bottom> <action b="0" s="0" o="0" des="Kole Calhoun remains in the game as the right fielder. " des_es="Kole Calhoun permanece en el juego como el jardinero derecho. " event="Defen

我试图解析MLB GameDay中可用的信息。下面是我正在使用的一个示例文件:

具体来说,下面是一个XML输出示例:

<bottom>
<action b="0" s="0" o="0" des="Kole Calhoun remains in the game as the right fielder. " des_es="Kole Calhoun permanece en el juego como el jardinero derecho. " event="Defensive Switch" tfs="010840" tfs_zulu="2014-04-06T01:08:40Z" player="594777" pitch="5"/>
<atbat num="50" b="4" s="0" o="0" start_tfs="010846" start_tfs_zulu="2014-04-06T01:08:46Z" batter="514888" pitcher="572140" des="Jose Altuve walks. " des_es="Jose Altuve recibe base por bolas. " event="Walk" b1="514888" b2="" b3="">
<pitch sv_id="140405_200702" des="Ball" des_es="Bola mala" type="B" start_speed="90.6" pitch_type="FT"/>
<pitch sv_id="140405_200718" des="Ball" des_es="Bola mala" type="B" start_speed="90.8" pitch_type="FF"/>
<pitch sv_id="140405_200738" des="Ball" des_es="Bola mala" type="B" start_speed="91.5" pitch_type="FT"/>
<pitch sv_id="140405_200757" des="Ball" des_es="Bola mala" type="B" start_speed="90.2" pitch_type="FF"/>
</atbat>
<atbat num="51" b="1" s="1" o="2" start_tfs="011113" start_tfs_zulu="2014-04-06T01:11:13Z" batter="461882" pitcher="572140" des="Jesus Guzman grounds into a double play, third baseman John McDonald to second baseman Howie Kendrick to first baseman Albert Pujols. Jose Altuve out at 2nd. " des_es="Jesus Guzman batea rodado batea para doble matanza, tercera base John McDonald a segunda base Howie Kendrick a primera base Albert Pujols. Jose Altuve a cabo a 2da. " event="Grounded Into DP" b1="" b2="" b3="">
<pitch sv_id="140405_200849" des="Called Strike" des_es="Strike cantado" type="S" start_speed="90.2" pitch_type="FT"/>
<pitch sv_id="140405_200915" des="Ball" des_es="Bola mala" type="B" start_speed="74.0" pitch_type="CU"/>
<pitch sv_id="140405_200941" des="In play, out(s)" des_es="En juego, out(s)" type="X" start_speed="83.7" pitch_type="CH"/>
</atbat>
<atbat num="52" b="2" s="3" o="3" start_tfs="011242" start_tfs_zulu="2014-04-06T01:12:42Z" batter="474892" pitcher="572140" des="Chris Carter called out on strikes. " des_es="Chris Carter se poncha sin tirarle. " event="Strikeout" b1="" b2="" b3="">
<pitch sv_id="140405_201027" des="Ball" des_es="Bola mala" type="B" start_speed="73.5" pitch_type="CU"/>
<pitch sv_id="140405_201044" des="Ball" des_es="Bola mala" type="B" start_speed="91.2" pitch_type="FT"/>
<pitch sv_id="140405_201111" des="Called Strike" des_es="Strike cantado" type="S" start_speed="91.1" pitch_type="FT"/>
<pitch sv_id="140405_201132" des="Swinging Strike" des_es="Strike tirándole" type="S" start_speed="91.6" pitch_type="FT"/>
<pitch sv_id="140405_201155" des="Called Strike" des_es="Strike cantado" type="S" start_speed="92.5" pitch_type="FT"/>
</atbat>
</bottom>
理想情况下,
Action#init
将有一个名为
atbat
的新初始值设定项。问题是,如何获取我正在实例化的
操作
之后的
第一个atbat标记

在上面的示例中,如果我要抓取第一个
操作
,它还应该能够抓取下一个
atbat
兄弟,如下所示:

<atbat num="50" b="4" s="0" o="0" start_tfs="010846" start_tfs_zulu="2014-04-06T01:08:46Z" batter="514888" pitcher="572140" des="Jose Altuve walks. " des_es="Jose Altuve recibe base por bolas. " event="Walk" b1="514888" b2="" b3="">

这是未经测试的(我使用并建议使用它来解析XML),但应该可以:

@xml_doc.elements.each("inning/bottom/action") { |element| 
  at_bat = REXML::XPath.first(elem, 'following-sibling::atbat[1]')
  action = Action.new
  action.init(element, at_bat, @gid, @num)
  @bottom_actions.push action
}
# ...

使用现有项目,因此使用REXML。尝试了上述方法,虽然没有任何错误,但at_bat返回
nil
我已编辑了我的答案。您应该使用下面描述的
同级
XPath轴来获取第一个“atbat”元素。没问题!
[1]
第一个XPath选择器可能是多余的,但是,根据REXML内部的工作方式,可能是必要的,或者可能提供更好的性能。
@xml_doc.elements.each("inning/bottom/action") { |element| 
  at_bat = REXML::XPath.first(elem, 'following-sibling::atbat[1]')
  action = Action.new
  action.init(element, at_bat, @gid, @num)
  @bottom_actions.push action
}
# ...