Skip to content

Instantly share code, notes, and snippets.

@tgpfeiffer
Created July 21, 2012 17:38
Show Gist options
  • Save tgpfeiffer/3156517 to your computer and use it in GitHub Desktop.
Save tgpfeiffer/3156517 to your computer and use it in GitHub Desktop.
Setting an XML namespace in Scala
/*
* Let's assume we have an XML fragment in Scala like:
* <entry xmlns="http://www.w3.org/2005/Atom">
* <content xmlns="http://mysite.com/xml/someSchema">
* Hello <name>you</name>!
* </content>
* </entry>
* Then (_ \ "content") will leave you with:
* <content xmlns="http://mysite.com/xml/someSchema" xmlns="http://www.w3.org/2005/Atom">
* Hello <name>you</name>!
* </content>
* which might cause problems at some places since you have two non-prefixed
* namespaces mixed together. You might want to keep only one of them; the
* function below does exactly that.
*/
import scala.xml._
import scala.xml.transform._
def setMainNamespace(x: Node, uri: String) = {
// create a non-prefix namespace
val ns = new NamespaceBinding(null, uri, TopScope)
// create a RewriteRule that sets this as the only namespace
object setNs extends RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case Elem(prefix, label, attribs, scope, children @ _*) =>
Elem(prefix, label, attribs, ns, children.map(setNs) :_*)
case other => other
}
}
// call that rule
setNs(x)
}
/*
* Now, the following will work:
*
* scala> val x = <entry xmlns="http://www.w3.org/2005/Atom"><content xmlns="http://mysite.com/xml/someSchema">Hello <name>you</name>!</content></entry> \ "content"
* x: scala.xml.NodeSeq = NodeSeq(<content xmlns="http://mysite.com/xml/someSchema" xmlns="http://www.w3.org/2005/Atom">Hello <name>you</name>!</content>)
*
* scala> setMainNamespace(x head, "http://mysite.com/xml/someOtherSchema")
* res1: scala.xml.Node = <content xmlns="http://mysite.com/xml/someOtherSchema">Hello <name>you</name>!</content>
*
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment