3

我有一个 xml(存储在变量报告中),如下所示:

<wrapper>
    <Sample Id="SomeId1">
        <Tag Id="SomeTag">
          <Lane Id="1">
           [...]
          </Lane>
        </Tag>
    </Sample>
    <Sample Id="SomeId2">
        <Tag Id="SomeTag">
          <Lane Id="1">
           [...]
          </Lane>
        </Tag>
    </Sample>
</wrapper>

我想从“Sample”节点中提取“Id”属性。我阅读了以下文章http://www.codecommit.com/blog/scala/working-with-scalas-xml-support然后尝试:

(report \\ "Sample" \ "@Id").text

我得到一个空字符串作为返回:

scala> (report \\ "Sample" \ "@Id").text
res16: String = ""

但我应该有 "SomeId1SomeId2" 作为 return 。我做错了什么?

我发现了几个与我相似的问题。示例: Scala:XML 属性解析

4

5 回答 5

4

我让它像这样工作:

(xml \\ "Sample").map(n => (n \ "@Id").text)

=> scala.collection.immutable.Seq[String] = List(SomeId1, SomeId2)

必须有更好的解决方案……</p>

于 2012-08-01T12:41:46.563 回答
2

如果您使用选择器在具有多个元素\的 a 上选择一个属性,您将得到一个空结果,正如您从源代码中看到的那样:NodeSeq

def \(that: String): NodeSeq = {
  ...
  that match {
    case "" => fail
    case "_" => makeSeq(!_.isAtom)
    case _ if (that(0) == '@' && this.length == 1) => atResult
    case _ => makeSeq(_.label == that)
  }
}

我以前对此感到疑惑,如果我没记错的话,我无法确定这是记录在案的行为——我目前肯定找不到文档。

无论如何,当前的实现感觉就像是 hack,并导致一些奇怪的行为:

scala> val bar = <bar>{ <baz/>.copy(label = "@baz") }</bar>
bar: scala.xml.Elem = <bar><@baz></@baz></bar>

scala> <foo>{ bar }</foo> \\ "bar" \ "@baz"
res0: scala.xml.NodeSeq = NodeSeq()

scala> <foo>{ bar ++ bar }</foo> \\ "bar" \ "@baz"
res1: scala.xml.NodeSeq = NodeSeq(<@baz></@baz>, <@baz></@baz>)

这是一个反常的例子,但结果仍然非常可怕。

作为一种解决方法,我会亲自编写类似(report \\ "Sample").flatMap(_ \"@Id")获取NodeSeq属性文本元素的内容,然后text在需要时对其进行映射。

于 2012-08-01T16:22:17.733 回答
1

对此进行了更多实验,我找到了@Jean-Philippe Pellet 提供的解决方案的替代解决方案,我认为该解决方案更加清晰(即使我确信有更好的方法来做到这一点。)

report.\\("Sample").foreach(s => println(s.attribute("Id").get.text))

这将返回:

scala> report.\\("Sample").foreach(s => println(s.attribute("Id").get.text))
SomeId1
SomeId2

由于 \ 方法返回一个 NodeSeq,因此可以遍历每个 Node 并获取其属性并对其进行处理。在这种情况下,只需获取它们并将它们转换为 String 以打印它们,但我想这也将允许更复杂的操作。

于 2012-08-01T14:32:01.573 回答
0

以下:

(report \ "Sample").head \ "@Id"

生成包含您的属性的 NodeSeq。输入属性似乎需要一个节点(不幸的是,我没有找到关于该假设的文档 - 欢迎参考链接)

于 2012-08-01T15:07:11.843 回答
-3

您必须使用 [] 而不是 \

\\"Sample"[@Id]
于 2012-08-01T11:56:43.940 回答