basictransformer.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 154 行
SCALA
154 行
/* __ *\** ________ ___ / / ___ Scala API **** / __/ __// _ | / / / _ | (c) 2002-2007, LAMP/EPFL **** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **** /____/\___/_/ |_/____/_/ | | **** |/ **\* */// $Id: BasicTransformer.scala 12360 2007-07-19 14:28:36Z mcdirmid $package scala.xml.transform/** A class for XML transformations. * * @author Burak Emir * @version 1.0 */abstract class BasicTransformer extends Function1[Node,Node] { protected case class NeedsCopy(result: Seq[Node]) extends Throwable /** Returns a new node buffer with the first <code>pos</code> elements * from <code>ns</code>. * * @param pos .. * @param ns .. * @return .. */ protected def buffer(pos: Int, ns: Seq[Node]): NodeBuffer = { val nb = new NodeBuffer() var jt = ns.elements var j = 0; while (j < pos-1) { nb.append(jt.next) j += 1 } nb } /** Turns a nodebuffer into a sequence, so hashcode works. * * @param nb .. * @return .. */ protected def freeze(nb: NodeBuffer): Seq[Node] = { val arr = new Array[Node](nb.length) var i = 0 val it = nb.elements; while (it.hasNext) { arr(i) = it.next i += 1 } val seq: Seq[Node] = arr seq } protected def single(ns: Seq[Node]) = 1 == ns.length /** * @param n ... * @param ns ... * @return ... */ protected def unchanged(n: Node, ns: Seq[Node]) = single(ns) && (ns.elements.next.eq(n)) /** Call transform(Node) for each node in ns, append results * to NodeBuffer. */ def transform(it: Iterator[Node], nb: NodeBuffer): Seq[Node] = { while (it.hasNext) nb ++= transform(it.next); freeze(nb) } /** 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] = { var i = 0 val it = ns.elements try { while (it.hasNext) { val n = it.next val n2 = transform(n) if (!unchanged(n, n2)) { throw NeedsCopy(n2) } i += 1 } ns } catch { case NeedsCopy(n2) => val nb = buffer(i, ns) nb ++= (n2:Iterable[xml.Node]) transform(it, nb) } } def transform(n: Node): Seq[Node] = { if (n.typeTag$ < 0) n else { val ch = n.child val nch = transform(ch) if (ch.eq(nch)) n else Elem(n.prefix, n.label, n.attributes, n.scope, nch:_*) } } def apply(n: Node): Node = { val seq = transform(n) if (!single(seq)) throw new UnsupportedOperationException("transform must return single node for root"); else seq.elements.next }}/*class IdentityTransformer extends BasicTransformer { override def transform(n: Node): Seq[Node] = n.match { case <world/> => <xml-world/> case _ => super.transform(n); }}object Foo with Application { val tr = new IdentityTransformer; val n = tr( <hello><world/></hello> ); Console.println(n); val tr2 = new RewriteRule { final override val name = "A rule"; override def transform(n: Node) = n.match { case <a/> => <b/><c/> case _ => n } } val tr3 = new RewriteRule { final override val name = "E rule"; override def transform(n: Node) = n.match { case <e/> => <f><f/></f> case _ => n } } val tr4 = new RuleTransformer(tr2, tr3); val m = tr4( <hello><a/><e/></hello> ); Console.println(m);}*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?