使用Scala转换RewriteRule仅删除xml节点的第一个实例

时间:2015-06-24 17:10:06

标签: xml scala

我使用scala xml重写规则,并尝试仅删除给定节点的第一个实例(可能存在重复的节点)。但是,执行以下操作将删除节点的所有实例。

class RemoveFoo(foo: Foo) extends RewriteRule {
  override def transform(node: Node): Seq[Node] = node match {
    case node @ <foo>{ ch @ _* }</foo> 
        if (node \\ "bar").text.equals(foo.bar) && 
           (node \\ "value").text.equals(foo.value) => {
        Nil
    }
    case other => other
  }
}

<foo>
  <bar>first</bar>
  <value>one</value>
</foo>
<foo>
  <bar>first</bar>
  <value>two</value>
</foo>
<foo>
  <bar>first</bar>
  <value>one</value>
</foo>

应该成为

<foo>
  <bar>first</bar>
  <value>two</value>
</foo>
<foo>
  <bar>first</bar>
  <value>one</value>
</foo>

1 个答案:

答案 0 :(得分:1)

我认为你不能使用RewriteRule

您可以删除与foo对象对应的第一个Foo节点:

import scala.xml.NodeSeq

case class Foo(bar: String, value: String)

def removeFirstFoo(nodes: NodeSeq, foo: Foo): NodeSeq = {
  val (before, after) = nodes.span{ 
    case <foo>
           <bar>{bar}</bar>
           <value>{value}</value>
         </foo> if bar == foo.bar && value == foo.value => true
    case _ => false
  }
  before ++ after.drop(1)
}

val nodes = 
  <foos>
    <foo>
      <bar>first</bar>
      <value>one</value>
    </foo>
    <foo>
      <bar>first</bar>
      <value>two</value>
    </foo>
    <foo>
      <bar>first</bar>
      <value>one</value>
    </foo>
  </foos>

输出:

scala> removeFirstFoo(nodes \\ "foo", Foo("first", "one"))
res0: scala.xml.NodeSeq = 
NodeSeq(<foo>
      <bar>first</bar>
      <value>two</value>
    </foo>, <foo>
      <bar>first</bar>
      <value>one</value>
    </foo>)