3

这个问题中,提问者想要像这样转换文档:

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

正如我在那里的回答中指出的那样,Anti-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 zipper,我们就不再有 zipper,只是IndexedSeq- 我们不能有 a Zipper[(Node, Int)],因为定义是trait Zipper[+A <: Node] ....

是否有一种干净的方式来使用zipzipWithIndex在 Anti-XML 拉链上,使用 等进行一些其他操作map,最终得到仍然是拉链的东西?

4

1 回答 1

2

我想不出一种直接的方法来实现您所需要的,但是如果您愿意使用较低级别的功能,则可以使用 a 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

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

于 2012-06-22T16:15:31.080 回答