scala 使用名称空间访问XML属性

hmtdttj4  于 2023-02-08  发布在  Scala
关注(0)|答案(3)|浏览(143)

如何访问带有名称空间的属性?我的XML数据在一个表单中

val d = <z:Attachment rdf:about="#item_1"></z:Attachment>

但以下内容与属性不匹配

(d \\ "Attachment" \ "@about").toString

如果我从属性名称中移除名称空间组件,那么它就可以工作。

val d = <z:Attachment about="#item_1"></z:Attachment>
(d \\ "Attachment" \ "@about").toString

知道如何在Scala中使用名称空间访问属性吗?

yvfmudvl

yvfmudvl1#

API文档引用了以下语法ns \ "@{uri}foo"
在你的例子中,没有定义名称空间,Scala似乎认为你的属性是无前缀的,参见d.attributes.getClass
如果你这么做:

val d = <z:Attachment xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:about="#item_1"></z:Attachment>

然后:

scala> d \ "@{http://www.w3.org/1999/02/22-rdf-syntax-ns#}about"
res21: scala.xml.NodeSeq = #item_1

scala> d.attributes.getClass
res22: java.lang.Class[_] = class scala.xml.PrefixedAttribute
fgw7neuy

fgw7neuy2#

你总是可以

d match {
  case xml.Elem(prefix, label, attributes, scope, children@_*) =>
}

或者在您的情况下也匹配xml.Attribute

d match {
  case xml.Elem(_, "Attachment", xml.Attribute("about", v, _), _, _*) => v
}

// Seq[scala.xml.Node] = #item_1

但是,Attribute根本不关心前缀,因此如果需要前缀,需要显式使用PrefixedAttribute

d match {
  case xml.Elem(_, "Attachment", xml.PrefixedAttribute("rdf", "about", v, _), _, _*) => v
}

然而,当有多个属性时,就会出现问题。有人知道如何修复这个问题吗?

31moq8wy

31moq8wy3#

假设我们有

val d = <z:Attachment id="foo" rdf:about="#item_1"></z:Attachment>

要访问属性的值,在scala-xml中有

d \@ "id"

但是它不适用于名称空间。不过,你可以添加一个方法来处理名称空间,如下所示:

implicit class EasyNode(node: scala.xml.Node):
  def \@@(attributeName: String): String = node.attributes.head.asAttrMap(attributeName)

然后像这样使用它:

d \@@ "rdf:about"

对我有用。

相关问题