gpt4 book ai didi

xml - 消除重复项,使用 scala.xml.transform.RuleTransformer 更改标签

转载 作者:数据小太阳 更新时间:2023-10-29 02:35:31 24 4
gpt4 key购买 nike

我有以下 XML:

<tree>
<leaf id="1"/>
<leaf id="1"/>
</tree>

我想做的是摆脱重复的 <leaf/> s(在整个 XML 文档中),并将它们替换为单个 <new-leaf/>像这样:

<tree>
<new-leaf id="1"/>
</tree>

我写了以下内容 RewriteRule ,我相信它应该已经完成​​了这个(请原谅状态):

import scala.xml._
import scala.xml.transform._

class UniqueLeaves extends RewriteRule {

var leafIds = Set.empty[String]

override def transform(node: Node): Seq[Node] = node match {
case e: Elem if ((e.label == "leaf") && !leafIds.contains((e \\ "@id").text)) => {
leafIds += (e \\ "@id").text
<new-leaf id={(e \\ "@id")} />
}
case e: Elem if (e.label == "leaf") => Seq.empty
case _ => node
}

}

不幸的是,使用 RuleTransformer给我以下内容:

scala> val tree = <tree><leaf id="1"/><leaf id="1"/></tree>
scala> println(new RuleTransformer(new UniqueLeaves).transform(tree))
<tree/>

我假设这是因为 RuleTransformer calls transform on the RewriteRule multiple times , 并使用非第一次调用输出 <new-leaf>节点,它返回一个空的 Seq在我的比赛中。

非常感谢有关使这项工作(并且是无状态的)的任何提示。

最佳答案

对于任何有类似问题的人,我找到了以下解决方案:

def removeDuplicates(tree: Node): Node = {
var ids = Set.empty[String]
def recurse(node: Node): Seq[Node] = node match {
case e: Elem if (e.label == "leaf") => {
val id = (e \\ "@id").text
ids.contains(id) match {
case true => Seq.empty
case _ => {
ids = ids + id
<new-leaf id={id}/>
}
}
}
case e: Elem => e.copy(child = e.nonEmptyChildren.map(recurse(_).headOption).flatten)
case _ => node
}
recurse(tree).head
}

这是有效的,因为它手动处理节点遍历,而不是使用 RuleTransformer#transform,因此不会多次迭代同一节点(尽管它仍然是有状态的,不幸的是)。

关于xml - 消除重复项,使用 scala.xml.transform.RuleTransformer 更改标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21391942/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com