在Anti-XML中压缩拉链

时间:2012-06-21 17:30:45

标签: xml scala zipper anti-xml

this question中,提问者想要转换这样的文档:

<text>
  The capitals of Bolivia are <blank/> and <blank/>.
</text>

进入这个:

<text>
  The capitals of Bolivia are <input name="blank.1"> and <input name="blank.2">.
</text>

正如我在my answer there中所指出的那样,Anti-XMLzippers为这个问题提供了一个干净的解决方案。例如,以下内容可用于重命名空白元素:

import com.codecommit.antixml._

val q = <text>The capitals of Bolivia are <blank/> and <blank/>.</text>.convert

(q \\ "blank").map(_.copy(name = "input")).unselect

不幸的是,以下情况不起作用:

(q \\ "blank").zipWithIndex.map { case (el, i) => el.copy(
  name = "input",
  attrs = Attributes("name" -> "blank.%d".format(i + 1))
)}.unselect

因为当我们zipWithIndex拉链时,我们不再有拉链,只有IndexedSeq - 我们不能拥有Zipper[(Node, Int)]因为定义是{ {1}}。

是否有一种干净的方法可以在Anti-XML拉链上使用trait Zipper[+A <: Node] ...zip,使用zipWithIndex等进行一些其他操作,并最终得到一些仍然是拉链?

1 个答案:

答案 0 :(得分:2)

我无法想到实现所需内容的直接方式,但如果您愿意使用较低级别的功能,则可以使用fold,例如:

val blanks = q \\ "blank"

(0 until blanks.size).foldLeft(blanks) {case (z, i) => z.updated(i, z(i).copy(
  name = "input",
  attrs = Attributes("name" -> "blank.%d".format(i + 1)))
)}.unselect

请注意,拉链是一个随机访问容器,因此在这种情况下效率不应该是一个问题。