Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing XML attributes with namespaces

Tags:

parsing

xml

scala

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?

like image 765
cake3d Avatar asked Sep 07 '10 14:09

cake3d


People also ask

Can XML attributes have namespaces?

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.

Can a namespace have attributes?

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.

Which XML attribute is used to define 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.

Why do we use namespaces in XML?

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.


2 Answers

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
like image 103
huynhjl Avatar answered Oct 13 '22 05:10

huynhjl


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?

like image 36
Debilski Avatar answered Oct 13 '22 04:10

Debilski