Scala - 从xml中完全删除命名空间

时间:2012-09-21 17:08:01

标签: xml scala

我有一些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>

我想通过这个xml并完全删除所有命名空间,无论它们在哪里。我如何用Scala做到这一点?

 <item name="ed" test="true">
  <blah>
     <node>value</node>
  </blah>
</item>

我一直在查看RuleTransform并复制属性等,但我可以删除命名空间或删除属性但不删除命名空间并保留属性。

2 个答案:

答案 0 :(得分:6)

标记是Elem个对象,命名空间由scope值控制。所以要摆脱它你可以使用:

xmlElem.copy(scope = TopScope)

然而,这是一个不可变的递归结构,因此您需要以递归方式执行此操作:

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
}

此函数将复制XML树,删除所有节点上的范围。您可能还必须从属性中删除范围。

答案 1 :(得分:1)

以下内容应递归删除命名空间以及元素和属性。

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
  }
}

它至少适用于以下测试用例:

<foo xmlns:xoox="http://example.com/xoox">
  <baz xoox:asd="first">123</baz>
  <xoox:baz xoox:asd="second">456</xoox:baz>
</foo>