1

我现在正在处理 XML 转换。例如,

  • 将所有节点替换<a><b>
  • <c x = "xxx"><d y="xxx">等替换所有节点。

我正在使用标准的scala.xml RewriteRuleRuleTransformer. 我将其扩展RewriteRule并传递给一个RuleTransformer实例,该实例将规则应用于 XML。

我知道还有其他工具可以完成这项工作:lenses、、zippers等等。它们可以根据需要转换 XML 吗?与我目前的方法相比,它们有什么优势?

4

1 回答 1

1

首先附注:Scala XML 场景非常可悲。Anti-XML很有希望,但现在大部分都被放弃了(Arktekk 让它在 2.10 上工作,但我不确定这种开发有多活跃)。不过, Anti-XML 确实有一个非常简洁的 zipper 实现,它允许您编写如下内容:

import com.codecommit.antixml._

val myDoc = <foo><a/><c x="xxx"/><a bar="baz"><b/></a></foo>.convert

def replaceA(e: Elem) = (e \\ "a").map(_.copy(name = "AAA")).unselect

def replaceXxxC(e: Elem) = (e \\ "c").filter(
  _.attrs.get("x").exists(_ == "xxx")
).map(_ => <d y="xxx"/>.convert).unselect

接着:

scala> println(replaceA(myDoc))
<foo><AAA/><c x="xxx"/><AAA bar="baz"><b/></AAA></foo>

scala> println(replaceXxxC(myDoc))
<foo><a/><d y="xxx"/><a bar="baz"><b/></a></foo>

基本思想是您使用选择器,例如\\导航到 XML、使用map等在本地进行“更改”,然后使用unselect. 这是使用 zippers(或镜头)进行 XML 转换的主要好处——您可以获得非常类似于命令式的编辑语法(它看起来或多或少有点像导航和本地更改),而且还具有不变性的所有好处。

Scales XML也允许您做这种事情,但它相当复杂。

于 2014-06-12T21:52:34.720 回答