3

在 Scala REPL 中:

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

input\\@"innerTag"

=>

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

我如何阻止 Scala 这样做?为什么不能只给我<innerTag> </innerTag>?我怎样才能阻止这种情况发生(或xmlns简单地删除属性)?

谢谢!

澄清:我的总体任务是分割一个 XML 文件并重新组合它。因此,该节点将从根节点(具有 xmlns 属性)下方获取,然后重新集成到再次具有 xmlns 的根节点下的文档中。

4

4 回答 4

3

在您的输入文档中,<innerTag>具有逻辑命名空间"http://xyz",因为其父<outerTag>元素具有该命名空间。这就是 XML 命名空间的工作方式。

当您单独请求<innerTag>元素时,Scala 会从 parent 复制命名空间声明<outerTag>,因为命名空间是 的逻辑部分<innerTag>,即使它没有在初始文档中明确说明。

如果要删除命名空间,则必须执行一些额外的处理。

于 2009-10-21T15:41:29.580 回答
3

在 Scala 2.8.0 中使用命名参数和 Elem.copy():

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>
于 2009-10-21T16:45:12.173 回答
1

上帝,我希望我错过了什么。不可能这么尴尬!

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

还是我被 Scala 宠坏了,以至于认为这过于复杂?

于 2009-10-21T16:40:16.093 回答
1

在将转换应用于文档的子节点时,我遇到了一种类似的问题。生成的节点都具有节点上的 xmlns。

完成转换后,我使用以下功能“清理”文档以进行打印。

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) )}
于 2010-07-27T21:17:51.807 回答