summaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2004-03-12 20:08:43 +0000
committerburaq <buraq@epfl.ch>2004-03-12 20:08:43 +0000
commit6c1888cb456c1fd87594399ca9cdeec4485dfaac (patch)
tree8dfedddd4afde23835a83ec476d66935620ddccd /sources
parentc1df3809c679310c5acd6316ef7092792ae1f31c (diff)
downloadscala-6c1888cb456c1fd87594399ca9cdeec4485dfaac.tar.gz
scala-6c1888cb456c1fd87594399ca9cdeec4485dfaac.tar.bz2
scala-6c1888cb456c1fd87594399ca9cdeec4485dfaac.zip
changes to xml api
Diffstat (limited to 'sources')
-rw-r--r--sources/scala/tools/dtd2scala/DeclToScala.scala8
-rw-r--r--sources/scala/xml/Elem.scala53
-rw-r--r--sources/scala/xml/Node.scala160
-rw-r--r--sources/scala/xml/Text.scala15
-rw-r--r--sources/scala/xml/Utility.scala8
5 files changed, 113 insertions, 131 deletions
diff --git a/sources/scala/tools/dtd2scala/DeclToScala.scala b/sources/scala/tools/dtd2scala/DeclToScala.scala
index 95d3f94d71..4283fbba46 100644
--- a/sources/scala/tools/dtd2scala/DeclToScala.scala
+++ b/sources/scala/tools/dtd2scala/DeclToScala.scala
@@ -40,7 +40,7 @@ class DeclToScala(fOut:PrintWriter,
case "template" => {
lookup.update("objectName", objectName);
lookup.update("compressDefault", compress.toString());
- n.children.elements.foreach { n => writeNode(n) }
+ n.child.elements.foreach { n => writeNode(n) }
}
case "elementBinding" => {
for( val decl <- elemMap.values.elements ) {
@@ -48,7 +48,7 @@ class DeclToScala(fOut:PrintWriter,
lookup += "elementContainsText" -> decl.containsText.toString();
lookup += "elementContentModel" -> decl.contentModel;
curAttribs = decl.attribs;
- n.children.elements.foreach{ n => writeNode( n ) }
+ n.child.elements.foreach{ n => writeNode( n ) }
}
curAttribs = null;
lookup -= "elementName";
@@ -58,7 +58,7 @@ class DeclToScala(fOut:PrintWriter,
case "attributeAssign" => {
for( val aDecl <- curAttribs.keys.elements ) {
lookup += "attributeName" -> aDecl;
- n.children.elements.foreach{ n => writeNode( n ) }
+ n.child.elements.foreach{ n => writeNode( n ) }
}
lookup -= "attributeName";
}
@@ -66,7 +66,7 @@ class DeclToScala(fOut:PrintWriter,
case "attributeBinding" => {
for( val aDecl <- curAttribs.keys.elements ) {
lookup += "attributeName" -> aDecl;
- n.children.elements.foreach{ n => writeNode( n ) }
+ n.child.elements.foreach{ n => writeNode( n ) }
}
lookup -= "attributeName";
}
diff --git a/sources/scala/xml/Elem.scala b/sources/scala/xml/Elem.scala
index 950a85f49f..bd4aabb054 100644
--- a/sources/scala/xml/Elem.scala
+++ b/sources/scala/xml/Elem.scala
@@ -1,39 +1,42 @@
package scala.xml ;
-import scala.collection.immutable.{Map,ListMap} ;
+import scala.collection.mutable.HashMap ;
-case class Elem( name:String, children:Node* ) extends AttributedNode {
+case class Elem( label:String, child:Node* ) extends Node with Similarity {
- /** Returns the symbol name as a string.
- */
- def label:String = name;
+ def similar( x:Any ) = {
+ x match {
+ case that:Node => (label == that.label) && child.similar( that.child )
+ case _ => false;
+ }
+ }
- /** Returns the list of children of this symbol.
- def children: NodeSeq = new NodeSeq( List.fromIterator(
- elems.elements map ( x => x match {
- case n:Node => n;
- case _ => Text(x.toString());
- })));
- */
+ private val hmap = new HashMap[String,String]();
- /** Returns a map representing the attributes of this node.
+ /** the attributes axis - default is Nil
*/
- def attributes: Map[String, String] = ListMap.Empty;
+ def attribute: Seq[Pair[String, String]] = hmap.elements.toSeq( hmap.size );
- /** returns a new symbol with updated attributes
+ /** returns a new element with updated attributes
*/
- final def %(attrs: List[Pair[String, String]]) =
- new Elem( name, children:_* ) {
- val themap = Elem.this.attributes.incl( attrs );
- override def attributes = themap;
+ final def %(attrs: Seq[Pair[String, String]]) = {
+ val newmap = new HashMap[String,String]();
+ for( val p <- hmap.elements ) { newmap += p._1 -> p._2 };
+ for( val p <- attrs ) { newmap += p._1 -> p._2 };
+ new Elem( label, child:_* ) {
+ private val hmap = newmap;
+ //override def attribute = newmap.elements.toSeq( newmap.size );
};
-
+ }
/** returns a new symbol with updated attribute
*/
- final def %(attr: Pair[String, String]) =
- new Elem( name, children:_* ) {
- val themap = Elem.this.attributes.incl( attr );
- override def attributes = themap;
+ final def %(attr: Pair[String, String]) = {
+ val newmap = new HashMap[String,String]();
+ for( val p <- hmap.elements ) { newmap += p._1 -> p._2 };
+ newmap += attr._1 -> attr._2;
+ new Elem( label, child:_* ) {
+ private val hmap = newmap;
+ //override def attribute = newmap.elements.toSeq( newmap.size );
};
-
+ }
}
diff --git a/sources/scala/xml/Node.scala b/sources/scala/xml/Node.scala
index f050b35dc1..00c5d88549 100644
--- a/sources/scala/xml/Node.scala
+++ b/sources/scala/xml/Node.scala
@@ -9,108 +9,90 @@
package scala.xml ;
+import scala.collection.mutable.AppendBuffer ;
-/** Trait for representation of XML elements. These are created by
- * a dtd2scala binding tool
+/** Trait for representing XML using nodes of a labelled tree.
+ * This trait contains an implementation of a subset of XPath for navigation.
*/
trait Node {
- /** the label of this XML node */
- def label: String;
- /** the children of this XML node */
- def children: Seq[Node];
- /** the string representation of this XML node */
- def toXML: String;
- /** projection function. Similar to XPath, use this./'foo to get a list
+ /** QName (the label of this node). I.e. "foo" for &lt;foo/&gt;) */
+ def label: String;
+
+ /** attribute axis */
+ def attribute: Seq[ Pair[String,String] ];
+
+ final def apply(key: String): Option[String] = {
+ val it = attribute.elements.filter { x => key == x._1 };
+ if( it.hasNext ) Some( it.next._2 ) else None
+ }
+
+ /** child axis (all children of this node) */
+ def child: Seq[Node];
+
+ /** descendant axis (all descendants of this node) */
+ def descendant:Seq[Node] = child.toList.flatMap {
+ x => x::x.descendant.asInstanceOf[List[Node]]
+ } ;
+
+ /** descendant axis (all descendants of this node) */
+ def descendant_or_self:Seq[Node] = this::child.toList.flatMap {
+ x => x::x.descendant.asInstanceOf[List[Node]]
+ } ;
+
+ override def equals( x:Any ):boolean = x match {
+ case that:Node =>
+ //Console.print("(Node)");
+ that.label == this.label &&
+ that.attribute.similar( this.attribute ) &&
+ that.child.similar( this.child )
+ case _ => false
+ }
+
+ /** projection function. Similar to XPath, use this \ 'foo to get a list
* of all children of this node that are labelled with "foo".
* The document order is preserved.
*/
- def |(that:Symbol): NodeSeq = new NodeSeq({
- val iter = children.elements;
- if( "_" == that.name ) {
- List.fromIterator( iter );
- } else {
- var res:List[Node] = Nil;
- for( val x <- iter; x.label == that.name ) {
- res = x::res;
- }
- res.reverse
+ def \(that:Symbol): NodeSeq = {
+ new NodeSeq({
+ val iter = child.elements;
+ that.name match {
+
+ case "_" => iter.toList;
+ case _ =>
+ var res:List[Node] = Nil;
+ for( val x <- child.elements; x.label == that.name ) {
+ res = x::res;
+ }
+ res.reverse
}
});
+ }
- /** projection function. Similar to XPath, use this./#'foo to get a list
- * of all descendants of this node that are labelled with "foo".
- * Use /'_ as a wildcard.
+ /** projection function. Similar to XPath, use this \\ 'foo to filter
+ * all nodes labelled with "foo" from the descendant_or_self axis.
* The document order is preserved.
*/
- def ||(that:Symbol): NodeSeq = new NodeSeq({
- var res:List[Node] = Nil;
- var tmp:List[Node] = Nil;
- for( val x <- children.elements ) {
- if ( x.label == that.name || "_" == that.name )
- tmp = x::tmp;
- tmp = tmp:::(x||(that)).toList;
- res = res:::tmp;
- tmp = Nil
- }
- res;
- });
-
-}
-
-/* a wrapper that adds a filter method */
-class NodeSeq(theList:List[Node]) extends Seq[Node] {
- val res = theList.flatMap ( x => List.fromIterator( x.children.elements ));
-
- /** 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: Symbol) = if( "_" == that.name ) {
- new NodeSeq( res )
- } else {
- new NodeSeq( res.filter( y => y.label == that.name ))
+ def \\(that:Symbol): NodeSeq = {
+ new NodeSeq(
+ that.name match {
+ case "_" => this.descendant_or_self;
+ case _ => this.descendant_or_self.asInstanceOf[List[Node]].
+ filter( x => x.label == that.name );
+ /*
+ val res = new AppendBuffer[Node]();
+ if( this.label == that.name )
+ res.append( this );
+ res.append( this.child.elements.flatMap {
+ x => //x.\\(that).elements
+ }.toSeq);
+ res.toList
+ */
+ })
}
+ override def hashCode() = Utility.hashCode(label, attribute.toList.hashCode(), child);
+ /** string representation of this node */
+ override def toString() = Utility.toXML(this);
- /** projection function. Similar to XPath, use this./'foo to get a list
- * of all children of this node that are labelled with "foo"
- * Use ||'_ as a wildcard. The document order is preserved.
- */
- def ||(that: Symbol): NodeSeq = new NodeSeq(
- if ( "_" == that.name ) {
- theList.flatMap ( x => (x||'_).toList )
- } else {
- theList.flatMap ( x => {
- if( x.label == that.name )
- x::(x||(that)).toList;
- else
- (x||(that)).toList;
- })
- });
-
- override def toList:List[Node] = theList;
-
- /* Seq methods */
- def length = theList.length;
- def elements = theList.elements ;
- def apply( i:int ) = theList.apply( i );
- /* forwarding list methods
- def isEmpty: boolean = theList.isEmpty;
- def head: Node = theList.head;
- def tail: List[Node] = theList.tail;
-
- override def toString():String = "Node"+theList.toString();
-
- override def filter(p: Node => Boolean): NodeList =
- new NodeList( theList.filter( p ) );
-
- override def foreach(f: Node => Unit): Unit = theList.foreach( f );
-
- override def flatMap[b](f: Node => List[b]): List[b] = theList.flatMap( f );
-
- override def :::[b >: Node](prefix: List[b]): List[b] = theList.:::( prefix );
- */
-
- //the == method cannot be forwarded :-(
}
diff --git a/sources/scala/xml/Text.scala b/sources/scala/xml/Text.scala
index bb1ec0354c..1c5ab0ddb2 100644
--- a/sources/scala/xml/Text.scala
+++ b/sources/scala/xml/Text.scala
@@ -12,6 +12,7 @@ package scala.xml;
import scala.collection.Map ;
/** an XML node for text (PCDATA). Used in both non-bound and bound XML representations
+ * @author Burak Emir
* @param text the text contained in this node
**/
@@ -21,19 +22,15 @@ case class Text( text:String ) extends Node {
*/
def label = "#PCDATA";
- /** always returns an empty list
- */
- final def children = Nil;
+ /** always empty */
+ final def attribute = Nil;
+ /** always empty */
+ final def child = Nil;
override def hashCode() = text.hashCode();
- /** returns "Text("+raw text+")"
- */
+ /** returns text, with some characters escaped according to XML spec */
override def toString() = Utility.escape( text );
- /** returns PCDATA text, with some characters escaped according to XML spec
- */
- override def toXML = Utility.escape( text );
-
}
diff --git a/sources/scala/xml/Utility.scala b/sources/scala/xml/Utility.scala
index fd9eda8e5d..818df1b0b6 100644
--- a/sources/scala/xml/Utility.scala
+++ b/sources/scala/xml/Utility.scala
@@ -37,15 +37,15 @@ object Utility {
def toXML( n:Node ):String = n match {
case Text( t ) =>
escape( t );
- case x:AttributedNode => {
+ case x:Node => {
val s = new StringBuffer();
s.append('<');
s.append( x.label );
- if( null != x.attributes ) {
- s.append( attr2xml( x.attributes.elements ) );{}
+ if( x.attribute.length != 0 ) {
+ s.append( attr2xml( x.attribute.elements ) );{}
}
s.append('>');
- s.append( toXML( x.children.elements ) );
+ s.append( toXML( x.child.elements ) );
s.append("</");
s.append( x.label );
s.append('>');