How one can access attributes with namespaces? My XML data are in a form
val d = <z:Attachment rdf:about="#item_1"></z:Attachment>
but the following does not match the attribute
(d \\ "Attachment" \ "@about").toString
If I remove the namespace component from the attribute's name then it works.
val d = <z:Attachment about="#item_1"></z:Attachment>
(d \\ "Attachment" \ "@about").toString
Any idea how to access attributes with namespaces in Scala?
An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.
An attribute is not considered a child of its parent element. An attribute never inherits the namespace of its parent element. For that reason an attribute is only in a namespace if it has a proper namespace prefix. An attribute can never be in a default namespace.
XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax.
One of the primary motivations for defining an XML namespace is to avoid naming conflicts when using and re-using multiple vocabularies. XML Schema is used to create a vocabulary for an XML instance, and uses namespaces heavily.
The API documentation refers to the following syntax ns \ "@{uri}foo"
.
In your example there is no namespace defined, and it seems Scala considers your attribute as unprefixed. See d.attributes.getClass
.
Now if you do this:
val d = <z:Attachment xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" rdf:about="#item_1"></z:Attachment>
Then:
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
You can always do
d match {
case xml.Elem(prefix, label, attributes, scope, children@_*) =>
}
or in your case also match on xml.Attribute
d match {
case xml.Elem(_, "Attachment", xml.Attribute("about", v, _), _, _*) => v
}
// Seq[scala.xml.Node] = #item_1
However, Attribute
does not care about the prefix at all, so if you need that, you need to explicitly use PrefixedAttribute
:
d match {
case xml.Elem(_, "Attachment", xml.PrefixedAttribute("rdf", "about", v, _), _, _*) => v
}
There is a problem, however, when there are multiple attributes. Anyone knows how to fix this?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With