summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-08-03 10:21:30 +0000
committerburaq <buraq@epfl.ch>2004-08-03 10:21:30 +0000
commit6274b6d50aa396cdc96440acfff37ffad09606b5 (patch)
treeb6c1c95307179e5fb9c433378f150ec3e82736f9
parent05dd3314d6e5370a56ddb73addc67d120f43560d (diff)
downloadscala-6274b6d50aa396cdc96440acfff37ffad09606b5.tar.gz
scala-6274b6d50aa396cdc96440acfff37ffad09606b5.tar.bz2
scala-6274b6d50aa396cdc96440acfff37ffad09606b5.zip
traversing of xml nodes
-rw-r--r--sources/scala/xml/NodeTraverser.scala25
-rw-r--r--sources/scala/xml/PrettyPrinter.scala116
-rw-r--r--sources/scala/xml/Utility.scala98
-rw-r--r--sources/scala/xml/parsing/ConstructingHandler.scala2
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);
{