XML转换如何在Scala中工作

时间:2015-05-13 11:44:51

标签: xml scala

我正在寻找一个应用程序错误,这会使scala.xml.BasicTransformer在无限循环中运行。首先,我正在阅读BasicTransformer.scala以了解transform(见下文)如何运作:

abstract class BasicTransformer extends Function1[Node, Node] {

 // ...

  protected def unchanged(n: Node, ns: Seq[Node]) =
    ns.length == 1 && (ns.head == n)

  def transform(ns: Seq[Node]): Seq[Node] = {
    val (xs1, xs2) = ns span (n => unchanged(n, transform(n)))

    if (xs2.isEmpty) ns
    else xs1 ++ transform(xs2.head) ++ transform(xs2.tail)
  }

... // rest of the code

}

你能解释一下

吗?
  • 为什么transform使用span
  • 调用unchanged
  • 如何确保始终终止于任何ns

1 个答案:

答案 0 :(得分:1)

据我了解,span基本上将Seq分成两个Seqs,其中:

  1. 第一个Seq包含与过滤器功能匹配的元素。
  2. 第二个Seq 开头,第一个与过滤功能不匹配的元素。
  3. Seq#span(...)可以找到xs1的更多技术说明。

    转换函数似乎只是递归地将转换应用于XML树中的所有节点,并且应该始终终止。

    在跨越节点的Seq后,xs2包含应用API docs的元素(请注意,这是与您粘贴的变换不同的变换)不会更改n。 xs1从第一个元素开始,其中将变换应用于元素会更改元素。

    然后使用xs2完成,但继续处理transform(n: Node):它将xs2应用于transform(ns: Seq[Node])的第一个元素,将xs2应用于剩余的xs2 transform(n: Node)中的元素。

    " while(true)"不断变小和变小,直到它最终变空,并且函数终止。

    编辑: 我正在考虑这个问题,并且我意识到跨度调用并非严格必要,似乎它们可能已经递归并且只是做了一个head :: tail split,但我想这个实现更优化了?它确实为每个节点调用了System.out.println("hi");两次,但是转换没有改变。