Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here it is. Since NamespaceBinding is nested (each ns has a parent, except TopScope), we need to recurse to fix that. Also, each ns has an URI and a prefix, and we need to change both.</p> <p>The function below will change just one particular URI and prefix, and it will check all namespaces, to see if either prefix or URI needs changing. It will change a prefix or a URI independent of each other, which might not be what is wanted. Not a big deal fixing that, though.</p> <p>As for the rest, just pattern match on Elem to recurse into each part of the XML. Ah, yes, it changes the prefix of the elements too. Again, if that's not what is wanted, it's easy to change.</p> <p>The code assumes there is no need to recurse into "other" parts of XML -- the rest will usually be Text elements. Also, it assumes there is no namespace elsewhere. I'm no expert on XML, so I could be wrong on both counts. Once more, it should be easy to change that -- just follow the pattern.</p> <pre><code>def changeNS(el: Elem, oldURI: String, newURI: String, oldPrefix: String, newPrefix: String): Elem = { def replace(what: String, before: String, after: String): String = if (what == before) after else what def fixScope(ns: NamespaceBinding): NamespaceBinding = if(ns == TopScope) TopScope else new NamespaceBinding(replace(ns.prefix, oldPrefix, newPrefix), replace(ns.uri, oldURI, newURI), fixScope(ns.parent)) def fixSeq(ns: Seq[Node]): Seq[Node] = for(node &lt;- ns) yield node match { case Elem(prefix, label, attribs, scope, children @ _*) =&gt; Elem(replace(prefix, oldPrefix, newPrefix), label, attribs, fixScope(scope), fixSeq(children) : _*) case other =&gt; other } fixSeq(el.theSeq)(0).asInstanceOf[Elem] } </code></pre> <p>This produces an unexpected result, though. The scope is getting added to all elements. That's because NamespaceBinding does not define a equals method, thus using reference equality. I have opened a ticket for it, <a href="https://lampsvn.epfl.ch/trac/scala/ticket/2138" rel="noreferrer">2138</a>, which has already been closed, so Scala 2.8 won't have this problem.</p> <p>Meanwhile, the following code will work properly. It keeps a cache of namespaces. It also decomposes NamespaceBinding into a list before handling it.</p> <pre><code> def changeNS(el: Elem, oldURI: String, newURI: String, oldPrefix: String, newPrefix: String): Elem = { val namespaces = scala.collection.mutable.Map.empty[List[(String, String)],NamespaceBinding] def replace(what: String, before: String, after: String): String = if (what == before) after else what def unfoldNS(ns: NamespaceBinding): List[(String, String)] = ns match { case TopScope =&gt; Nil case _ =&gt; (ns.prefix, ns.uri) :: unfoldNS(ns.parent) } def foldNS(unfoldedNS: List[(String, String)]): NamespaceBinding = unfoldedNS match { case knownNS if namespaces.isDefinedAt(knownNS) =&gt; namespaces(knownNS) case (prefix, uri) :: tail =&gt; val newNS = new NamespaceBinding(prefix, uri, foldNS(tail)) namespaces(unfoldedNS) = newNS newNS case Nil =&gt; TopScope } def fixScope(ns: NamespaceBinding): NamespaceBinding = if(ns == TopScope) ns else { val unfoldedNS = unfoldNS(ns) val fixedNS = for((prefix, uri) &lt;- unfoldedNS) yield (replace(prefix, oldPrefix, newPrefix), replace(uri, oldURI, newURI)) if(!namespaces.isDefinedAt(unfoldedNS)) namespaces(unfoldedNS) = ns // Save for future use if(fixedNS == unfoldedNS) ns else foldNS(fixedNS) } def fixSeq(ns: Seq[Node]): Seq[Node] = for(node &lt;- ns) yield node match { case Elem(prefix, label, attribs, scope, children @ _*) =&gt; Elem(replace(prefix, oldPrefix, newPrefix), label, attribs, fixScope(scope), fixSeq(children) : _*) case other =&gt; other } fixSeq(el.theSeq)(0).asInstanceOf[Elem] } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload