diff options
-rw-r--r-- | sources/scala/xml/Node.scala | 2 | ||||
-rw-r--r-- | sources/scala/xml/NodeSeq.scala | 59 | ||||
-rw-r--r-- | sources/scala/xml/PrettyPrinter.scala | 6 | ||||
-rw-r--r-- | test/files/jvm/xmlLiterals.scala | 2 | ||||
-rw-r--r-- | test/files/jvm/xmlstuff.check | 19 | ||||
-rw-r--r-- | test/files/jvm/xmlstuff.scala | 39 |
6 files changed, 99 insertions, 28 deletions
diff --git a/sources/scala/xml/Node.scala b/sources/scala/xml/Node.scala index 31fd7174a5..ac00ea1fce 100644 --- a/sources/scala/xml/Node.scala +++ b/sources/scala/xml/Node.scala @@ -37,7 +37,7 @@ trait Node { def child: Seq[Node]; /** descendant axis (all descendants of this node) */ - def descendant: List[Node] = child.toList.flatMap { + def descendant:List[Node] = child.toList.flatMap { x => x::x.descendant } ; diff --git a/sources/scala/xml/NodeSeq.scala b/sources/scala/xml/NodeSeq.scala index 73d15843ea..5b5941b4ed 100644 --- a/sources/scala/xml/NodeSeq.scala +++ b/sources/scala/xml/NodeSeq.scala @@ -9,34 +9,47 @@ package scala.xml ; -/* a wrapper that adds some XPath navigation method */ +/** a wrapper around Seq[Node] that adds XPath and comprehension methods */ class NodeSeq( theSeq:Seq[Node] ) extends Seq[Node] { + def length = theSeq.length; def elements = theSeq.elements ; def apply( i:int ) = theSeq.apply( i ); - /** projection function. Similar to XPath, use this./'foo to get a list + /** 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( x.child ) ) + yield y + case _ => for( val x <- this; + val y <- new NodeSeq( 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. + * Use \ "_" as a wildcard. The document order is preserved. */ - def \ (that: String):NodeSeq = { - that match { - case "_" => - val it = elements.flatMap { x:Node => x.child.elements }; - new NodeSeq( it.toList ); - case _ => - val list = elements.flatMap( y => - y.child.elements.filter{ z:Node => z.label == that }).toList; - new NodeSeq( list ); - } - } - - def \\ ( that:String ):NodeSeq = { - val list = (elements.flatMap { x:Node => x.descendant_or_self.elements }).toList; - that match { - case "_" => new NodeSeq( list ); - case _ => new NodeSeq( list.filter { z:Node => z.label == that }); - } + + def \\ ( that:String ):NodeSeq = that match { + case "_" => for( val x <- this; + val y <- new NodeSeq( x.descendant_or_self )) + yield { y } + case _ => for( val x <- this; + val y <- new NodeSeq( x.descendant_or_self ); + y.label == that) + yield { y } } override def toString() = theSeq.elements.foldLeft ("") { @@ -57,4 +70,8 @@ class NodeSeq( theSeq:Seq[Node] ) extends Seq[Node] { new NodeSeq( asList flatMap { x => f(x).asList }) } + def filter( f:Node => boolean ):NodeSeq = { + new NodeSeq( asList filter f ) + } + } diff --git a/sources/scala/xml/PrettyPrinter.scala b/sources/scala/xml/PrettyPrinter.scala index e62139b3aa..b6a6e4a525 100644 --- a/sources/scala/xml/PrettyPrinter.scala +++ b/sources/scala/xml/PrettyPrinter.scala @@ -111,7 +111,7 @@ class PrettyPrinter( width:Int, step:Int ) { /* returns a formatted string containing well-formed XML **/ - def toPrettyXML( n:Node ):String = { + def format( n:Node ):String = { reset(); traverse( n, 0 ); val sb = new StringBuffer(); @@ -135,10 +135,10 @@ class PrettyPrinter( width:Int, step:Int ) { /* returns a formatted string containing well-formed XML nodes. **/ - def toPrettyXML( ns:Seq[Node] ):String = { + def format( ns:Seq[Node] ):String = { var sb2 = new StringBuffer(); for( val n <- ns.elements ) { - sb2.append( toPrettyXML( n )) + sb2.append( format( n )) } sb2.toString(); } diff --git a/test/files/jvm/xmlLiterals.scala b/test/files/jvm/xmlLiterals.scala index c45f2a1cd5..13b2591790 100644 --- a/test/files/jvm/xmlLiterals.scala +++ b/test/files/jvm/xmlLiterals.scala @@ -221,7 +221,7 @@ object Test03Servlet { def main( args:Array[String] ) = { val x = doGetXML(); Console.println( x ); - Console.println( new PrettyPrinter( 80, 2 ).toPrettyXML( x )); + Console.println( new PrettyPrinter( 80, 2 ).format( x )); } } diff --git a/test/files/jvm/xmlstuff.check b/test/files/jvm/xmlstuff.check index afe3a6839f..f73797cb2a 100644 --- a/test/files/jvm/xmlstuff.check +++ b/test/files/jvm/xmlstuff.check @@ -20,3 +20,22 @@ passed ok passed ok NodeSeq passed ok +<result> + <title>Blabla</title> + <entry> + <title>Blabla</title> + <remarks>Hallo Welt.</remarks> + </entry> +</result><result> + <title>Blubabla</title> + <entry> + <title>Blubabla</title> + <remarks>Hello Blu</remarks> + </entry> +</result><result> + <title>Blubabla</title> + <entry> + <title>Blubabla</title> + <remarks>rem 2</remarks> + </entry> +</result> diff --git a/test/files/jvm/xmlstuff.scala b/test/files/jvm/xmlstuff.scala index ff6c2e03ed..3954f6f383 100644 --- a/test/files/jvm/xmlstuff.scala +++ b/test/files/jvm/xmlstuff.scala @@ -138,7 +138,7 @@ object Test with Application { ); - assertSameElements( + assertEquals( new NodeSeq(List( parsedxml2 )) \\ "_", @@ -192,6 +192,41 @@ object Test with Application { x.attribute("value") + y.attribute("bazValue")+ "!" }, new NodeSeq(List(Text("38!"),Text("58!"))) - ) + ); + + val books = + <bks> + <book><title>Blabla</title></book> + <book><title>Blubabla</title></book> + <book><title>Baaaaaaalabla</title></book> + </bks>; + + val reviews = + <reviews> + <entry><title>Blabla</title> + <remarks> + Hallo Welt. + </remarks> + </entry> + <entry><title>Blubabla</title> + <remarks> + Hello Blu + </remarks> + </entry> + <entry><title>Blubabla</title> + <remarks> + rem 2 + </remarks> + </entry> + </reviews>; + + Console.println( new scala.xml.PrettyPrinter(80, 5).format ( + for( val t <- books \\ "title"; + val r <- reviews \\ "entry"; r \ "title" == t ) yield + <result> + { t } + { r } + </result> + )); } |