Reputation: 2706
I have some xml:
<item name="ed" test="true"
xmlns="http://www.somenamespace.com"
xmlns:xsi="http://www.somenamespace.com/XMLSchema-instance">
<blah>
<node>value</node>
</blah>
</item>
I want to go through this xml and remove all namespaces completely, no matter where they are. How would I do this with Scala?
<item name="ed" test="true">
<blah>
<node>value</node>
</blah>
</item>
I've been looking at RuleTransform and copying over attributes etc, but I can either remove the namespaces or remove the attributes but not remove the namespace and keep the attributes.
Upvotes: 7
Views: 2031
Reputation: 4492
The following should recursively remove namespaces and from elements and attributes.
def removeNamespaces(node: Node): Node = {
node match {
case elem: Elem => {
elem.copy(
scope = TopScope,
prefix = null,
attributes = removeNamespacesFromAttributes(elem.attributes),
child = elem.child.map(removeNamespaces)
)
}
case other => other
}
}
def removeNamespacesFromAttributes(metadata: MetaData): MetaData = {
metadata match {
case UnprefixedAttribute(k, v, n) => new UnprefixedAttribute(k, v, removeNamespacesFromAttributes(n))
case PrefixedAttribute(pre, k, v, n) => new UnprefixedAttribute(k, v, removeNamespacesFromAttributes(n))
case Null => Null
}
}
It worked for at least the following test case:
<foo xmlns:xoox="http://example.com/xoox">
<baz xoox:asd="first">123</baz>
<xoox:baz xoox:asd="second">456</xoox:baz>
</foo>
Upvotes: 3
Reputation: 2095
The tags are Elem
objects and the namespace is controlled by the scope
value. So to get rid of it you could use:
xmlElem.copy(scope = TopScope)
However this is an immutable recursive structure so you need to do this in a recursive manner:
import scala.xml._
def clearScope(x: Node):Node = x match {
case e:Elem => e.copy(scope=TopScope, child = e.child.map(clearScope))
case o => o
}
This function will copy the XML tree removing the scope on all the nodes. You may have to remove the scope from the attributes too.
Upvotes: 11