diff options
author | buraq <buraq@epfl.ch> | 2004-08-03 10:21:30 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2004-08-03 10:21:30 +0000 |
commit | 6274b6d50aa396cdc96440acfff37ffad09606b5 (patch) | |
tree | b6c1c95307179e5fb9c433378f150ec3e82736f9 | |
parent | 05dd3314d6e5370a56ddb73addc67d120f43560d (diff) | |
download | scala-6274b6d50aa396cdc96440acfff37ffad09606b5.tar.gz scala-6274b6d50aa396cdc96440acfff37ffad09606b5.tar.bz2 scala-6274b6d50aa396cdc96440acfff37ffad09606b5.zip |
traversing of xml nodes
-rw-r--r-- | sources/scala/xml/NodeTraverser.scala | 25 | ||||
-rw-r--r-- | sources/scala/xml/PrettyPrinter.scala | 116 | ||||
-rw-r--r-- | sources/scala/xml/Utility.scala | 98 | ||||
-rw-r--r-- | sources/scala/xml/parsing/ConstructingHandler.scala | 2 |
4 files changed, 179 insertions, 62 deletions
diff --git a/sources/scala/xml/NodeTraverser.scala b/sources/scala/xml/NodeTraverser.scala index 41b7a1fc93..2772d4786c 100644 --- a/sources/scala/xml/NodeTraverser.scala +++ b/sources/scala/xml/NodeTraverser.scala @@ -11,15 +11,26 @@ package scala.xml ; import scala.collection.mutable ; -abstract class NodeTraverser[A](handle: parsing.MarkupHandler[A]) { +class NodeTraverser[A](handle: parsing.MarkupHandler[A]) { - def traverse(n: Node): Iterable[A] = { - val nb = new mutable.ArrayBuffer[A](); - val it = n.child.elements; - while(it.hasNext) { - nb.appendAll(traverse(it.next)); - } + def traverse(n: Node): Iterable[A] = n match { + case Text(t) => handle.text(0,t); + case ProcInstr(ta,te) => handle.procInstr(0,ta,te); + case Comment(t) => handle.comment(0,t); + case CharData(cd) => handle.charData(0,cd); + case EntityRef(n) => handle.entityRef(0,n); + case _ => + val nb = new mutable.ArrayBuffer[A](); + val it = n.child.elements; + while(it.hasNext) { + nb.appendAll(traverse(it.next)); + } handle.element(0, n.namespace, n.label, n.attributes.toMap, nb) } } + +class NodeSubstitution(handle: parsing.ConstructingHandler) + extends NodeTraverser[Node](handle) with Function1[Node,Iterable[Node]] { + def apply(n: Node) = traverse(n); +} diff --git a/sources/scala/xml/PrettyPrinter.scala b/sources/scala/xml/PrettyPrinter.scala index 9cd38c89cb..fd4c86484d 100644 --- a/sources/scala/xml/PrettyPrinter.scala +++ b/sources/scala/xml/PrettyPrinter.scala @@ -102,6 +102,21 @@ class PrettyPrinter( width:Int, step:Int ) { sb.toString(); } + protected def rootStartTag(n: Node) = { + val sb = new StringBuffer("<"); + Utility.appendPrefixedName( n.namespace, n.label, pmap, sb ); + Utility.attr2xml( n.namespace, n.attributes.elements, pmap, sb ); + if(( pmap.size != 1 )|| !pmap.contains("")) + for( val c <- pmap.elements ) { + sb.append(" xmlns:"); + sb.append(c._2); + sb.append("=\""); + sb.append(c._1); + sb.append('"'); + } + sb.append('>'); + sb.toString(); + } protected def startTag(n: Node) = { val sb = new StringBuffer("<"); Utility.appendPrefixedName( n.namespace, n.label, pmap, sb ); @@ -110,6 +125,13 @@ class PrettyPrinter( width:Int, step:Int ) { sb.toString(); } + protected def endTag(n: Node) = { + val sb = new StringBuffer("</"); + Utility.appendPrefixedName( n.namespace, n.label, pmap, sb ); + sb.append('>'); + sb.toString(); + } + /** appends a formatted string containing well-formed XML with * given namespace to prefix mapping to the given stringbuffer * @param n the node to be serialized @@ -119,7 +141,7 @@ class PrettyPrinter( width:Int, step:Int ) { def format(n: Node, pmap: Map[String,String], sb: StringBuffer ): Unit = { reset(); this.pmap = pmap; - traverse( n, 0 ); + traverse1( n, 0 ); var cur = 0; //Console.println( items.reverse ); for( val b <- items.reverse ) b match { @@ -154,35 +176,111 @@ class PrettyPrinter( width:Int, step:Int ) { makeBox( ind, node.toString() ); case _:Node => - val test = node.toString(); - - if( ( test.length() < width - cur ) // all ? - &&( !breakable( node ))) { + val sb = new StringBuffer(); + val test = { Utility.toXML1(node,pmap,sb); sb.toString()}; + if(( test.length() < width - cur )&&( !breakable( node ))){ // all ? makeBox( ind, test ); } else { // start tag + content + end tag //Console.println(node.label+" ind="+ind); val stg = startTag( node ); - val endTag = "</"+node.label+">"; - val len2 = node.label.length() + 1; + val etg = endTag( node ); + val len2 = pmap(node.namespace).length() + node.label.length() + 2; if( stg.length() < width - cur ) { // start tag fits makeBox( ind, stg ); makeBreak(); traverse( node.child.elements, ind + step ); - makeBox( ind, endTag ); + makeBox( ind, etg ); } else if( len2 < width - cur ) { // <start label + attrs + tag + content + end tag makeBox( ind, stg.substring( 0, len2 )); makeBreak(); + /*{ //@todo + val sq:Seq[String] = stg.split(" "); + val it = sq.elements; + it.next; + for( val c <- it ) { + makeBox( ind+len2-2, c ); + makeBreak(); + } + }*/ makeBox( ind, stg.substring( len2, stg.length() )); makeBreak(); traverse( node.child.elements, ind + step ); - makeBox( cur, endTag ); + makeBox( cur, etg ); + } else { + makeBox( ind, test ); + makeBreak(); } } + } + } + + /** @param tail: what we'd like to sqeeze in */ + protected def traverse1( node:Node, ind:int ):Unit = { + node match { + + case _:Text | _:CharData | _:Comment | _:EntityRef | _:ProcInstr => + makeBox( ind, node.toString() ); + + case _:Node => { + // start tag + content + end tag + //Console.println(node.label+" ind="+ind); + val stg = rootStartTag( node ); + val etg = endTag( node ); + val len2 = pmap(node.namespace).length() +node.label.length() + 2; + + if( stg.length() < width - cur ) { // start tag fits + + makeBox( ind, stg ); + makeBreak(); + traverse( node.child.elements, ind + step ); + makeBox( ind, etg ); + + } else if( len2 < width - cur ) { + val sq:Seq[String] = stg.split(" "); + val it = sq.elements; + var tmp = it.next; + makeBox( ind, tmp ); + var curlen = cur + tmp.length(); + while( it.hasNext ) { + var tmp = it.next; + if( tmp.length() + curlen + 1 < width ) { + makeBox( ind, " " ); + makeBox( ind, tmp ); + curlen = curlen + tmp.length() + 1; + } else { + makeBreak(); + makeBox( len2+1, tmp ); + curlen = len2+1; + } + } + // <start label + attrs + tag + content + end tag + //makeBox( ind, stg.substring( 0, len2 )); + //makeBreak(); + /*{ //@todo + val sq:Seq[String] = stg.split(" "); + val it = sq.elements; + it.next; + for( val c <- it ) { + makeBox( ind+len2-2, c ); + makeBreak(); + } + }*/ + //makeBox( ind, stg.substring( len2, stg.length() )); + makeBreak(); + traverse( node.child.elements, ind + step ); + makeBox( cur, etg ); + } else { // it does not fit, dump everything + val sb = new StringBuffer(); + val tmp = { Utility.toXML1(node,pmap,sb); sb.toString()}; + makeBox( ind, tmp ); + makeBreak(); + } } + } } protected def traverse( it:Iterator[Node], ind:int ):unit = { diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala index 9b734ebd00..c8ffde0a65 100644 --- a/sources/scala/xml/Utility.scala +++ b/sources/scala/xml/Utility.scala @@ -131,59 +131,67 @@ object Utility { ** with the given namespace prefix mapping * @param n the root node */ - def toXML( x:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = x match { - case Text( t ) => - sb.append( escape( t ) ); - case _ if x.typeTag$ < 0 => - sb.append( x.toString() ); - case _ => { - sb.append('<'); - appendPrefixedName( x.namespace, x.label, pmap, sb ); - if( x.attributes.length != 0 ) { - attr2xml( x.namespace, x.attributes.elements, pmap, sb ) - } - if( (pmap.size != 1)||pmap.get("").isEmpty) { - for( val Pair(ns,pref) <- pmap.elements ) { - sb.append(' '); - sb.append("xmlns"); - if( pref.length() > 0 ) sb.append(':'); - sb.append(pref); - sb.append("=\""); - sb.append(ns); - sb.append('"') - } - } - sb.append('>'); - for( val c <- x.child.elements ) { - toXML1( c, pmap, sb ); + def toXML( x:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = { + x match { + case Text( t ) => + sb.append( escape( t ) ); + case _ if x.typeTag$ < 0 => + sb.append( x.toString() ); + case _ => { + sb.append('<'); + appendPrefixedName( x.namespace, x.label, pmap, sb ); + if( x.attributes.length != 0 ) { + attr2xml( x.namespace, x.attributes.elements, pmap, sb ) + } + if( (pmap.size != 1)||pmap.get("").isEmpty) { + for( val Pair(ns,pref) <- pmap.elements ) { + sb.append(' '); + sb.append("xmlns"); + if( pref.length() > 0 ) sb.append(':'); + sb.append(pref); + sb.append("=\""); + sb.append(ns); + sb.append('"') + } + } + sb.append('>'); + for( val c <- x.child.elements ) { + toXML1( c, pmap, sb ); + } + sb.append("</"); + appendPrefixedName( x.namespace, x.label, pmap, sb ); + sb.append('>'); } - sb.append("</"); - appendPrefixedName( x.namespace, x.label, pmap, sb ); - sb.append('>'); } } /** serializes a tree to the given stringbuffer ** with the given namespace prefix mapping * @param n the root node */ - def toXML1( x:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = x match { - case Text( t ) => - sb.append( escape( t ) ); - case _ if x.typeTag$ < 0 => - sb.append( x.toString() ); - case _ => { - sb.append('<'); - appendPrefixedName( x.namespace, x.label, pmap, sb ); - if( x.attributes.length != 0 ) { - attr2xml( x.namespace, x.attributes.elements, pmap, sb ) - } - sb.append('>'); - for( val c <- x.child.elements ) { - toXML1( c, pmap, sb ); + def toXML1( x:Node, pmap:Map[String,String], sb:StringBuffer ):Unit = { + //Console.print("toString: "+x.toString()); + x match { + case Text( t ) => + //Console.println("case Text"); + sb.append( escape( t ) ); + case _ if x.typeTag$ < 0 => + //Console.println("case _ if tag"); + sb.append( x.toString() ); + case _ => { + //Console.println("case _, class"+x.getClass()); + sb.append('<'); + appendPrefixedName( x.namespace, x.label, pmap, sb ); + if( x.attributes.length != 0 ) { + attr2xml( x.namespace, x.attributes.elements, pmap, sb ) + } + sb.append('>'); + for( val c <- x.child.elements ) { + toXML1( c, pmap, sb ); + } + sb.append("</"); + appendPrefixedName( x.namespace, x.label, pmap, sb ); + sb.append('>'); } - sb.append("</"); - appendPrefixedName( x.namespace, x.label, pmap, sb ); - sb.append('>'); } } diff --git a/sources/scala/xml/parsing/ConstructingHandler.scala b/sources/scala/xml/parsing/ConstructingHandler.scala index cf2070320f..c8c315ecfc 100644 --- a/sources/scala/xml/parsing/ConstructingHandler.scala +++ b/sources/scala/xml/parsing/ConstructingHandler.scala @@ -10,7 +10,7 @@ class ConstructingHandler extends MarkupHandler[Node] { //def attributeNamespaceDecl(pos: int, uri: String) = NamespaceDecl(uri); - def element(pos: int, uri: String, label: String, attrMap1: Map[Pair[String,String],Attribute], args: mutable.Buffer[Node]) = { + def element(pos: int, uri: String, label: String, attrMap1: Map[Pair[String,String],Attribute], args: mutable.Buffer[Node]):Iterable[Node] = { var attrs = new Array[Attribute](attrMap1.size); { |