Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 在Scala中查找特定标签的所有节点并替换它们_Xml_Scala - Fatal编程技术网

Xml 在Scala中查找特定标签的所有节点并替换它们

Xml 在Scala中查找特定标签的所有节点并替换它们,xml,scala,Xml,Scala,我有一个XML节点: <a> <b> <c> foo </c> </b> <b2> bar </b2> </a> 我怎样才能做到这一点呢?使用标准库并没有什么好办法,但下面的方法可以奏效: def replaceAllBs(elem: Elem): Elem = elem.copy( ch

我有一个XML节点:

<a>
    <b>
        <c>
            foo
        </c>
    </b>
    <b2>
           bar
   </b2>
</a>

我怎样才能做到这一点呢?

使用标准库并没有什么好办法,但下面的方法可以奏效:

def replaceAllBs(elem: Elem): Elem = elem.copy(
  child = elem.child.map {
    case elem: Elem if elem.label == "b" => <b3>baz</b3>
    case elem: Elem => replaceAllBs(elem)
    case other => other
  }
)

在树中进行选择,进行一些更改,然后使用
取消选择
返回顶部。如果您对这种方法感兴趣,可以主动维护它,并提供另一种Scala XML拉链实现(尽管它在语法上比反XML的要大一些)。

简单递归实现:

import scala.xml.{Elem, Node}

def replace(xml: Node)(p: Node => Boolean)(elem: Node): Node = xml match {
    case x: Node if p(x) => elem
    case Elem(prefix, label, attribs, scope, child @ _*) =>
        Elem(prefix, label, attribs, scope, child.map(replace(_)(p)(elem)): _*)
    case x: Node => x
}

val xml = <a><k/><b><c>text</c></b></a>
replace(xml)(_.label == "c")(<z>TEXT</z>)
import scala.xml.{Elem,Node}
def replace(xml:Node)(p:Node=>Boolean)(elem:Node):Node=xml匹配{
情形x:如果p(x)=>elem,则为节点
案例元素(前缀、标签、属性、范围、子@*)=>
元素(前缀、标签、属性、作用域、子映射(替换(p)(元素)):*)
案例x:节点=>x
}
val xml=text
替换(xml)(文本)

@Core\u Dumped:感谢您提出的编辑,这确实是一个打字错误,我自己也改正了,因为在其他用户拒绝您的编辑后,我似乎无法接受您的编辑。
(elem \\ "b").map(_ => <b3>baz</b3>.convert).unselect.head
import scala.xml.{Elem, Node}

def replace(xml: Node)(p: Node => Boolean)(elem: Node): Node = xml match {
    case x: Node if p(x) => elem
    case Elem(prefix, label, attribs, scope, child @ _*) =>
        Elem(prefix, label, attribs, scope, child.map(replace(_)(p)(elem)): _*)
    case x: Node => x
}

val xml = <a><k/><b><c>text</c></b></a>
replace(xml)(_.label == "c")(<z>TEXT</z>)