删除scala中的前缀属性(scala-xml)

时间:2014-11-20 19:36:36

标签: xml scala scala-xml

我正在尝试使用RuleTransformer删除Scala中带有前缀的属性。

以下内容适用于未加前缀的属性:

val xml = <foo><bar attr="attval">content</bar></foo>
val rw1 = new RewriteRule {
  override def transform(n: Node) = n match {
    case Elem(null, "bar", a, s, children @ _*) =>
      Elem(null, "bar", a.remove("attr"), TopScope, children: _*)
    case x => x
  }
}
val rt = new RuleTransformer(rw1)
rt(xml)

我没有成功使用带前缀的属性(请注意&#34; at&#34;&#34; bar&#34;元素的前缀为&#34; pre&#34;):< / p>

val xml = <foo><bar pre:attr="attval">content</bar></foo>
val rw1 = new RewriteRule {
  override def transform(n: Node) = n match {
    case Elem(null, "bar", a, s, children @ _*) =>
      Elem(null, "bar", a.remove("attr"), TopScope, children: _*)
    case x => x
  }
}
val rt = new RuleTransformer(rw1)
rt(xml)

我正在尝试使用

a.remove("pref",TopScope,"attr")

定义

MetaData.remove(namespace: String, scope: NamespaceBinding, key: String)

没有任何成功。

我是Scala初学者,如果这是一个微不足道的问题,请耐心等待。

2 个答案:

答案 0 :(得分:1)

由于其实现,您无法删除带有remove(String)的带前缀的属性:

来自Attribute.scala

def remove(key: String) =
  if (!isPrefixed && this.key == key) next
  else copy(next remove key)

如您所见,如果该属性带有前缀,则第一个分支条件为false。但是,同一个类中有不同的功能:

def remove(namespace: String, scope: NamespaceBinding, key: String) =
  if (this.key == key && (scope getURI pre) == namespace) next
  else copy(next.remove(namespace, scope, key))

只有在scope.getURI(pre) == namespace pre"pre"作为前缀时,分支才会成功,例如scope.getURI

NamespaceBinding.scala的实施属于def getURI(_prefix: String): String = if (prefix == _prefix) uri else parent getURI _prefix

prefix

其中所有三个,uriparentprefix都是该类的字段。因此,在您的示例中,"pre"必须为urinamespace必须是remove的字符串值,这是parent的第一个参数,{{1如果您不希望发生异常,则不能为null。

我对xml命名空间知之甚少,但我认为如果你的XML定义得很好,你需要有适当的值。如果您想要为此示例人工制作一些合适的值,则可以执行以下操作(在transform - 方法中):

case Elem(null, "bar", a, s, children @ _*) =>
  val scope = n.scope.copy(prefix = "pre", uri = "pre", parent = n.scope)
  Elem(null, "bar", a.remove("pre", scope, "attr"), TopScope, minimizeEmpty = true, children: _*)

请注意,我将parent设置为n.scope,在您的示例中,这是最高范围。

一个小注意事项:您使用的apply - Elem - 方法自Scala 2.10以来已弃用,因此我将minimizeEmpty设置为已将其更改为未弃用的方法true

答案 1 :(得分:1)

只是提供了我能够如何处理上述示例的方式,这要归功于此处给出的有用提示:

val xml = <foo><bar pre:attr="attval">content</bar></foo>
val rw1 = new RewriteRule {
    override def transform(n: Node) = n match {
      case Elem(null, "bar", _, _, _) =>
        n.asInstanceOf[Elem].copy(attributes = new UnprefixedAttribute("attr", "attval", Null))
    case x => x
  }
}  
val rt = new RuleTransformer(rw1)
rt(xml)

结果:

result: scala.xml.Node = <foo><bar attr="attval">content</bar></foo>