Question

In Scala REPL:

val input = <outerTag xmlns="http://xyz"> <innerTag> </innerTag> </outerTag>

input\\@"innerTag"

=>

<innerTag xmlns="http://xyz"> </innerTag>

How do I stop Scala do this? Why can't it just give me <innerTag> </innerTag>? How can I stop this happening (or remove the xmlns attributes simply)?

Thanks!

Joe

Clarification: My overall task is chopping up an XML file and recombining it. So this node will be taken from beneath the root node (which has the xmlns attribute) and then integrated back into a document under a root which again has the xmlns.

Was it helpful?

Solution

In your input document, <innerTag> has the logical namespace "http://xyz" because its parent <outerTag> element had that namespace. That's the way XML namespaces work.

When you ask for the <innerTag> element on its own, Scala copies the namespace declaration from the parent <outerTag>, because the namespace is a logical part of the <innerTag>, even if it wasn't explicitly stated in the initial document.

If you want to remove the namespace, you'll have to perform some additional processing to do so.

OTHER TIPS

Use named parameter and Elem.copy() in Scala 2.8.0:

scala> import scala.xml._
import scala.xml._

scala> val outer = <outerTag xmlns="http://xyz"><innerTag></innerTag></outerTag>
outer: scala.xml.Elem = <outerTag xmlns="http://xyz"><innerTag></innerTag></outerTag>

scala> outer \\ "innerTag" map { case e: Elem => e.copy(scope = TopScope) }
res0: scala.xml.NodeSeq = <innerTag></innerTag>

God, I hope I'm missing something. It can't be this awkward!

import scala.xml._
import scala.xml.tranform._

val rw = new RewriteRule { 
  override def transform(n: Node) = n match {
    case Elem(p, l, a, s, children@ _*) => Elem(p, l, a, TopScope, children: _*)
    case x => x
  }
  override def transform(ns: Seq[Node]): Seq[Node] = ns flatMap transform
}
val rt = new RuleTransformer(rw)

val input = <outerTag xmlns="http://xyz"> <innerTag> </innerTag> </outerTag>

val result = input \\ "innerTag" map rt

Or am I too spoiled with Scala to think this is overly complex?

I ran into a kind of similar problem when applying transforms to sub-nodes of a document. The resulting nodes all had the xmlns on the nodes.

After completing the transformation I used the following function to 'clean' the document for the purposes of printing.

def transformForPrinting(doc : Elem) : Elem = { 
 def stripNamespaces(node : Node) : Node = {
     node match {
         case e : Elem => 
             e.copy(scope = TopScope, child = e.child map (stripNamespaces))
         case _ => node;
     }
 }
 doc.copy( child = doc.child map (stripNamespaces) )}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top