1

备注:请考虑 XPath 语法死在这里,谢谢。

我有 xml 节点(实际上是 HTML),我想获取它的属性。

在 C# (HTMLAgilityPack) 中,我可以按名称获取属性对象。例如,有“a”节点我可以要求“href”属性。

在 Scala 中,xml.Node 中有“属性”方法,但这会返回一系列..节点。一个属性是一个节点?怎么可能有多个同名的属性?我完全不解。

此外,还有 xml.Attribute 类,但我没有看到它在 xml.Node 中使用。

我有 PiS 书,但 XML 章节很浅。

问题

我应该如何理解要求获取节点集合的属性?

IOW:返回节点集合选项而不是返回属性有什么意义?

  • option -- 如果没有属性,集合应该是空的,它是加倍语义
  • 集合——这意味着可能有多个属性,所以我很好奇在什么情况下我会得到大小 > 1 的集合
  • 节点——属性是非常简单的实体,为什么这种矫枉过正并暗示属性可以具有树结构
4

2 回答 2

4

您只想获取属性的值,是吗?在这种情况下,这很容易:

scala> val x = <foo this="xx" that="yy" />
x: scala.xml.Elem = <foo this="xx" that="yy"></foo>

scala> x.attribute("this")
res0: Option[Seq[scala.xml.Node]] = Some(xx)

scala> x.attribute("this").get.toString
res1: String = xx

我知道您说过您明确对 XPath 语法不感兴趣,但在这种情况下,它确实更简洁:

scala> x \ "@this"
res2: scala.xml.NodeSeq = xx

说了这么多,你应该知道,Scala 内置的 XML 处理中的属性处理存在很多问题。例如,参见thisthisthis

于 2011-11-12T11:09:15.957 回答
0

我意识到保罗的后续回答几乎涵盖了您的问题,但我想再补充几点:

  1. 我个人不喜欢 Scala XML 的设计,因为我写了一个替代库Scales Xml,但我不会称它设计糟糕。它的设计元素显然也足以构成 Anti-Xml 方法的基础(拥有子元素的元素、分组节点的概念等),但有许多怪癖——属性和文本作为容器是一个很大的问题。
  2. 我最近才将后代轴提交给 Scales - 它的贪婪性质与后代或自我不同 - 根据规范 //para 1并不意味着与位置路径 /descendant::para 1相同
  3. 我不确定您是否可以将糟糕的设计归咎于 Anti-Xml,因为它的缺席,它是一个年轻的项目(刚刚超过七个月?)而且他们可能根本还没有开始添加后代。

Scales 属性问题的直接答案是:

val pre = Namespace("uri:test").prefixed("pre")

val elem = Elem("fred"l, emptyAttributes + 
        ("attr", "value") +
        Attribute(pre("attr"), "value"))

println("attributes are a map " + elem.attributes("attr"))

println("attributes are a set " + (
  elem.attributes + ("attr", "new value")))

val xpath = top(elem) \@ pre("attr")

xpath foreach{ap => println(ap.name)}

给予

[info] attributes are a map Some(Attribute({}attr,value))
[info] attributes are a set ListSet(Attribute({}attr,new value), Attribute({uri:test}attr,value))
[info] {uri:test}attr

XPath 语法必须返回一个集合,因为它可以是到达匹配属性的任意数量的路径。元素属性本身是 QName 匹配的“attr”,这意味着没有命名空间和 attr 的 localName。为了更加健全,属性 QName 是:

type AttributeQName = EitherLike[PrefixedQName, NoNamespaceQName]

编译器确保没有本地名称只有 QNames 潜入。

顺便说一句,虽然我理解为什么类似 Scala XML XPath 的语法可能无趣,但您应该看看 Scales for XPath based querying。

既有基于 XPath 1.0 字符串的查询(尚未推送到非快照版本),也有一个内部 dsl,它可以让编译器/ide 帮助您(加上速度更快并直接使用 scala 代码的好处)。

于 2011-11-13T12:08:48.867 回答