在反XML荏苒拉链(Zipping zippers in Anti-XML)

2019-09-18 08:46发布

在这个问题中,提问者想转换文档是这样的:

<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>

正如我在注意我的回答有 , 防XML的拉链提供一个清洁的解决这个问题。 以下,例如,将重命名空白元的工作:

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 -ed拉链我们不再有拉链,只是一个IndexedSeq -我们不能有Zipper[(Node, Int)] ,因为定义是trait Zipper[+A <: Node] ...

有没有办法使用干净的方式zipzipWithIndex上的反XML拉链,做一些其他的操作与map等,并与东西,仍然是一个拉链结了?

Answer 1:

我想不出一个直接的方式来实现你所需要的,但如果你愿意去低级别的功能,你可以使用一个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

需要注意的是拉链是一个随机存取容器,所以效率不应该在这种情况下的问题。



文章来源: Zipping zippers in Anti-XML