1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id$
package scala.xml
package transform
/** A class for XML transformations.
*
* @author Burak Emir
* @version 1.0
*/
abstract class BasicTransformer extends Function1[Node,Node]
{
/**
* @param n ...
* @param ns ...
* @return ...
*/
protected def unchanged(n: Node, ns: Seq[Node]) =
ns.length == 1 && (ns.head == n)
/** Call transform(Node) for each node in ns, append results
* to NodeBuffer.
*/
def transform(it: Iterator[Node], nb: NodeBuffer): Seq[Node] =
it.foldLeft(nb)(_ ++= transform(_)).toSequence
/** Call transform(Node) to each node in ns, yield ns if nothing changes,
* otherwise a new sequence of concatenated results.
*/
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)
}
def transform(n: Node): Seq[Node] = {
if (n.doTransform) n match {
case Group(xs) => Group(transform(xs)) // un-group the hack Group tag
case _ =>
val ch = n.child
val nch = transform(ch)
if (ch eq nch) n
else Elem(n.prefix, n.label, n.attributes, n.scope, nch:_*)
}
else n
}
def apply(n: Node): Node = {
val seq = transform(n)
if (seq.length > 1)
throw new UnsupportedOperationException("transform must return single node for root");
else seq.head
}
}
|