Scala:给定一个Scala.xml.Node,什么';获取第二个(或第n个)子元素的最有效方法是什么?

Scala:给定一个Scala.xml.Node,什么';获取第二个(或第n个)子元素的最有效方法是什么?,xml,scala,Xml,Scala,给定一个scala.xml.Node对象(使用空格和元素作为子节点),获取第二个(或第n个)子元素的最有效方法是什么 通常我会选择内置的(节点\“foo”),但有时我不得不依赖元素的位置。例如,我可以有两个选择组,可以是foo或bar。该文件可以是 <something> <foo/> <foo/> </something> 或 等等。到目前为止,我得到的是: node.child.filter(_.isInstanceOf[sc

给定一个
scala.xml.Node
对象(使用空格和元素作为子节点),获取第二个(或第n个)子元素的最有效方法是什么

通常我会选择内置的
(节点\“foo”)
,但有时我不得不依赖元素的位置。例如,我可以有两个选择组,可以是
foo
bar
。该文件可以是

<something>
  <foo/>
  <foo/>
</something>


等等。

到目前为止,我得到的是:

node.child.filter(_.isInstanceOf[scala.xml.Elem])(1)

获取名为“foo”的第二个元素,如果未找到,则获取
None

(xml \ "foo").drop(1).headOption
或者,在大型XML结构的情况下更有效:

xml.child.toStream.partialMap { 
   case e: xml.Elem if e.label == "foo" => e
}.drop(1).headOption
(这是Scala 2.8的一部分)

更新

要获取第二个,无论名称如何:

 (xml \ "_") drop(1) headOption

我喜欢retronym的
drop(n).headOption
模式,因为它解释了当你的孩子少于
n
时的情况。但我认为您指的是第二个子节点(不包括文本节点),而不是
标记的第二个实例。记住这一点,结合您的答案或使用
partialMap

node.child.partialMap{case x:scala.xml.Elem => x}.drop(n).headOption

node.child.filter(_.isInstanceOf[scala.xml.Elem]).drop(n).headOption
这必须假设您不想在以下位置提取文本:

如果希望安全,可能需要定义一个函数来检查
hasNext


所有这些都只在2.8中进行了测试。

所以下降(n)。headOption为我带来了安全,但没有效率?由于child返回ArrayBuffer,所以使其可移植只会避免过滤成本,对吗?谢谢您的回答。为了澄清,正如@huynhjl所写的,我感兴趣的是第二个子元素,而不是foo的第二个实例。
node.child.partialMap{case x:scala.xml.Elem => x}.drop(n).headOption

node.child.filter(_.isInstanceOf[scala.xml.Elem]).drop(n).headOption
val node = <something><foo/>text</something>
node.child.iterator.filter(_.isInstanceOf[scala.xml.Elem]).drop(n).next