13

在 scala 中用于对文档执行以下 XPath 查询的最简单 API 是什么?

//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]

//s:Annotation[s:Content/s:Parameter[@role='id' and not(text())]]/@type

s被定义为特定命名空间的昵称)

我能找到的关于 Scala 的 XML 库的唯一文档没有关于执行复杂的真实 XPath 查询的信息。

我曾经为此喜欢JDOM(在 Java 中),但由于 JDOM 不支持泛型,因此在 Scala 中使用会很痛苦。(其他用于 Java 的 XML 库在 Java 中往往更加痛苦,但我承认我并不真正了解情况。)

4

5 回答 5

12
//s:Annotation[@type='attitude']/s:Content/s:Parameter[@role='type' and not(text())]

好吧,我不明白这个s:符号,也无法在 XPath 规范中找到它。但是,忽略这看起来像这样:

(
  (xml 
    \\ "Annotation" 
    filter (_ \ "@type" contains Text("x"))
  ) 
  \ "Content" 
  \ "Parameter" 
  filter (el => (el \ "@type" contains Text("type")) && el.isInstanceOf[Text])
)

请注意括号的必要性,因为\over的优先级更高filter。我已将格式更改为多行表达式,因为 Scala 等效项对于单行来说太冗长了。

不过,我无法回答有关名称空间的问题。不知道如何在搜索中与他们合作,如果可能的话。文档提到@{uri}attribute了前缀属性,没有提到任何关于前缀元素的内容。另外,请注意,您需要传递一个解析为所需名称空间的 uri,因为不支持搜索中的文字名称空间。

于 2010-06-16T22:14:52.117 回答
3

我想我会选择轻轻拉皮条XOM。XOM 作者决定不公开子节点等的集合有点可惜,但是在 Java 中这样做比在 Scala 中做的工作更多,优势更少。(而且它是一个设计良好的库。)

编辑:毕竟我结束了对 JDOM 的拉皮条,因为 XOM 不会提前编译 XPath 查询。由于这次我的大部分精力都集中在 XPath 上,因此我能够提出一个很好的模型来回避大多数泛型问题。getChildren提出合理的方法和in的通用getAttributes化版本应该不会太难(通过使用名称略有更改的新方法来拉皮条)。我不认为有解决方法,我不是确定。getAdditionalNamespacesorg.jdom.ElementgetContentgetDescendants

于 2010-06-17T14:23:57.790 回答
3

Scales Xml添加了基于字符串的完整 XPath 评估和内部 DSL,为查询提供了相当完整的覆盖范围

于 2011-11-04T22:31:32.163 回答
1

想当 scalaxmljaxen成熟时,我们将能够在 scala 的内置 XML 类上可靠地做到这一点。

于 2010-06-21T02:40:35.463 回答
0

我建议使用kantan.xpath

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

 input.evalXPath[List[String]](xp"/annotation[@type='attitude']/content/parameter[@role='type' and not(text())]/@value")

这产生:

res1: kantan.xpath.XPathResult[List[String]] = Success(List(foobar))
于 2017-10-26T14:36:49.593 回答