我意识到保罗的后续回答几乎涵盖了您的问题,但我想再补充几点:
- 我个人不喜欢 Scala XML 的设计,因为我写了一个替代库Scales Xml,但我不会称它设计糟糕。它的设计元素显然也足以构成 Anti-Xml 方法的基础(拥有子元素的元素、分组节点的概念等),但有许多怪癖——属性和文本作为容器是一个很大的问题。
- 我最近才将后代轴提交给 Scales - 它的贪婪性质与后代或自我不同 - 根据规范 //para 1并不意味着与位置路径 /descendant::para 1相同
- 我不确定您是否可以将糟糕的设计归咎于 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 代码的好处)。