6

我正在尝试使用 scala 运行 XPath 查询,但它似乎不起作用。我的 Xml 看起来像(简化):

<application>
  <process type="output" size ="23"> 
     <channel offset="0"/>
      ....
     <channel offset="4"/>
  </process>
  <process type="input" size ="16"> 
     <channel offset="20"/>
      ....
     <channel offset="24"/>
  </process>
</application>

我想processinput属性检索 ,为此我使用这个 XPath 查询:

//process[@type='input']

这应该可行,我用xpathtester验证了它 现在,我的 scala 代码如下所示:

import scala.xml._
val x = XML.loadFile("file.xml")

val process = (x \\ "process[@type='input']")  // will return empty NodeSeq() !!!

最终process是空的,它没有捕捉到我想要的东西。我是这样解决的:

val process = (x \\ "process" filter( _ \"@type" contains Text("input")))

这更丑陋。为什么我的原始查询不起作用的任何已知原因?

4

3 回答 3

4

不应使用“XPath”来描述 Scala 标准库支持的内容。XPath 是一种成熟的表达式语言,目前有两个最终版本,第三个正在开发中:

充其量你可以说 Scala 有一小部分受 XPath 启发的操作。因此,您不能指望在不做更多工作的情况下直接将 XPath 表达式粘贴到 Scala。

第三方库可以更好地支持实际的 XPath 表达式,包括:

  • 秤 Xml
    • 斯卡拉库
    • “提供比普通 Scala XML 更像 XPath 的体验,路径看起来像 XPath,并且也像它们一样工作(具有许多相同的功能和轴)”
    • 如果我理解得很好,它仍然不是真正的 XPath
    • 旨在与 Scala 很好地集成
  • 撒克逊人
    • Java 库
    • 开源
    • 对 XPath 2(和 XSLT 2)的完整且一致的支持
    • 有一个适用于 DOM 和其他数据模型的 XPath API,但目前没有特定的 Scala 支持
于 2013-04-02T17:36:07.050 回答
1

一种方法是使用kantan.xpath

import kantan.xpath._
import kantan.xpath.implicits._

val input = """
     | <application>
     |   <process type="output" size ="23">
     |      <channel offset="0"/>
     |      <channel offset="4"/>
     |   </process>
     |   <process type="input" size ="16">
     |      <channel offset="20"/>
     |      <channel offset="24"/>
     |   </process>
     | </application>
     | """.stripMargin

val inputs = input.evalXPath[List[Node]](xp"//process[@type='input']")

这会产生 a List[Node],但您可以检索具有更有趣类型的值 - 通道偏移列表,例如:

input.evalXPath[List[Int]](xp"//process[@type='input']/channel/@offset")
// This yields Success(List(20, 24))
于 2017-10-26T14:29:15.307 回答
0

我相信 scala xml 实现无法处理如此复杂的 XPath 查询。然而,创建一个小型丰富的包装器来减少混乱并不难,例如看看这个线程。使用建议的包装器,您可以像这样解决您的问题:

x \\ "process" \@ ("type", _ == "input")
于 2013-04-01T14:27:43.433 回答