blob: 56ab68a13081e52fb3c968cf4ece03f1187537c1 (
plain) (
blame)
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2004, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
** $Id$
\* */
package scala.xml ;
object NodeSeq {
final val Empty = new NodeSeq { def theSeq = Nil; }
def fromSeq(s:Seq[Node]):NodeSeq = new NodeSeq {
def theSeq = s;
}
def view(s:Seq[Node]):NodeSeq = fromSeq(s);
}
/** a wrapper around Seq[Node] that adds XPath and comprehension methods */
abstract class NodeSeq extends Seq[Node] {
def theSeq: Seq[Node];
def length = theSeq.length;
def elements = theSeq.elements ;
def apply( i:int ) = theSeq.apply( i );
/** structural equality */
override def equals( x:Any ) = x match {
case z:Node => ( length == 1 ) && z == apply( 0 )
case z:Seq[Node] => sameElements( z )
case _ => false;
}
/** projection function. Similar to XPath, use this \ "foo" to get a list
* of all elements of this sequence that are labelled with "foo".
* Use \ "_" as a wildcard. The document order is preserved.
*/
def \(that: String):NodeSeq = that match {
case "_" => for( val x <- this;
val y <- new NodeSeq { val theSeq = x.child; })
yield y
case _ => for( val x <- this;
val y <- new NodeSeq { val theSeq = x.child; };
y.label == that )
yield { y }
}
/** projection function. Similar to XPath, use this \\ 'foo to get a list
* of all elements of this sequence that are labelled with "foo".
* Use \ "_" as a wildcard. The document order is preserved.
*/
def \\ ( that:String ):NodeSeq = that match {
case "_" => for( val x <- this;
val y <- new NodeSeq { val theSeq = x.descendant_or_self })
yield { y }
case _ => for( val x <- this;
val y <- new NodeSeq { val theSeq = x.descendant_or_self };
y.label == that)
yield { y }
}
override def toString():String = theSeq.elements.foldLeft ("") {
(s:String,x:Node) => s + x.toString()
}
private var _asList:List[Node] = null;
def asList = {
if (_asList == null ) _asList = elements.toList;
_asList
}
def map( f:Node => Node ):NodeSeq = {
new NodeSeq{ final def theSeq = NodeSeq.this.asList map f }
}
def flatMap( f:Node => NodeSeq ):NodeSeq = {
new NodeSeq{ final def theSeq = NodeSeq.this.asList flatMap { x => f(x).asList }}
}
def filter( f:Node => boolean ):NodeSeq = {
new NodeSeq{ val theSeq = NodeSeq.this.asList filter f }
}
}
|