summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorburaq <buraq@epfl.ch>2003-08-27 10:23:08 +0000
committerburaq <buraq@epfl.ch>2003-08-27 10:23:08 +0000
commitd36d1e0e4c95a8082e5b6e8141d854ad98e79218 (patch)
tree11758dccf8d722050f5807f164fb50dd1c0e3a27
parent33bb8c9531a7b34612d0b5de0e73384525b12be9 (diff)
downloadscala-d36d1e0e4c95a8082e5b6e8141d854ad98e79218.tar.gz
scala-d36d1e0e4c95a8082e5b6e8141d854ad98e79218.tar.bz2
scala-d36d1e0e4c95a8082e5b6e8141d854ad98e79218.zip
added attributes to generic xml representation
-rw-r--r--sources/scala/xml/Element.scala5
-rw-r--r--sources/scala/xml/Generic.scala106
-rw-r--r--sources/scala/xml/PCDATA.scala18
-rw-r--r--sources/scala/xml/ScalaFactoryAdapter.scala50
4 files changed, 127 insertions, 52 deletions
diff --git a/sources/scala/xml/Element.scala b/sources/scala/xml/Element.scala
index e4d24f1918..0dce66ab1b 100644
--- a/sources/scala/xml/Element.scala
+++ b/sources/scala/xml/Element.scala
@@ -18,7 +18,7 @@ abstract class Element {
override def hashCode() = Element.hashValue( getName, getAttribs, getChildren );
def toXML: String = {
- "<" + getName + toXML_( getAttribs ) + ">"
+ "<" + getName + Generic.toXML( getAttribs ) + ">"
+ toXML_( getChildren )
+ "</" + getName +">"
}
@@ -28,6 +28,7 @@ abstract class Element {
case Nil => "";
}
+ /*
def toXML_( attrib:Map[ String, String ] ):String = {
def iterate( keys:Iterator[String] ) =
if( keys.hasNext )
@@ -42,7 +43,7 @@ abstract class Element {
if( attrib != null ) iterate( attrib.keys.elements ) else "";
}
-
+*/
override def toString() = getName.concat("(").concat(getChildren.toString().concat(")"));
/*
diff --git a/sources/scala/xml/Generic.scala b/sources/scala/xml/Generic.scala
index ac649d4656..bc760bcfef 100644
--- a/sources/scala/xml/Generic.scala
+++ b/sources/scala/xml/Generic.scala
@@ -1,5 +1,9 @@
package scala.xml;
+import scala.xml.javaAdapter.Map ;
+import scala.xml.javaAdapter.HashMap ;
+
+
/** Generic.load( <fileName> ) will load the xml document from file and
* create a tree with scala.Labelled, PCDATA and scala.Symbol objects.
* Text can appear within PCDATA at the leaves.
@@ -7,33 +11,109 @@ package scala.xml;
object Generic {
+ // utility functions
+
+ def iterToList[ a ]( iter:java.util.Iterator ):List[a] =
+ if( !iter.hasNext() )
+ Nil
+ else
+ (iter.next().asInstanceOf[ a ])::iterToList( iter ) ;
+
+ def mapToMap[a,b]( map:java.util.Map ):Map[a,b] = {
+
+ val keys:java.util.Iterator = map.keySet().iterator();
+ val res = new HashMap[a,b] ;
+
+ def iterToMap:Unit =
+ if( keys.hasNext() ) {
+ val key = keys.next();
+ val value = map.get( key ).asInstanceOf[ b ];
+ res.put( key.asInstanceOf[ a ], value.asInstanceOf[ b ]);
+ iterToMap
+ } else
+ () ;
+
+ iterToMap;
+ res
+ }
+
+ def toXML( attrib:Map[ String, String ] ):String = {
+ def iterate( keys:Iterator[String] ) =
+ if( keys.hasNext ) {
+ val key = keys.next;
+ " " + key + "=\"" + attrib.get( key ) + "\"";
+ } else {
+ ""
+ }
+
+ if( attrib != null ) iterate( attrib.keys.elements ) else "";
+ }
+
+ // attributes
+
+ trait Attribbed {
+
+ // only CDATA / String attributes for now
+ def attribs : Map[String,String] ;
+
+ }
+ // functions for generic xml loading, saving
+
def load( filename:String ):Labelled = {
val b = new GenericFactoryAdapter().loadXML( filename );
b.asInstanceOf[Labelled]
};
- class GenericFactoryAdapter extends FactoryAdapter() {
+ def save( filename:String, doc:Any ):Unit = {
+ import java.io.{FileOutputStream,Writer};
+ import java.nio.channels.{Channels,FileChannel};
+ def toXML( xs: List[Any], fc:Writer ):Unit = xs match {
+ case _::ys =>
+ toXML( xs.head, fc );
+ toXML( ys, fc );
+ case _ => ()
+ }
+ def toXML( doc: Any, fc:Writer ):Unit = doc match {
+ case PCDATA( s ) =>
+ fc.write( (doc.asInstanceOf[ PCDATA ]).toXML );
+ case Labelled( Symbol( tag ), xs ) =>
+ fc.write( "<" );
+ fc.write( tag );
+ fc.write( Generic.toXML(( doc.asInstanceOf[ Attribbed ])
+ .attribs ));
+ fc.write( ">" );
+ toXML( xs, fc );
+ fc.write( "</" );
+ fc.write( tag );
+ fc.write( ">" );
- import scala.xml.javaAdapter.Map ;
- import scala.xml.javaAdapter.HashMap ;
+ }
+ val fos = new FileOutputStream( filename );
+ val w = Channels.newWriter( fos.getChannel(), "ISO-8859-1" );
+ toXML( doc, w );
+ w.close();
+ fos.close();
+ }
- def iterToList[ a ]( iter:java.util.Iterator ):List[a] =
- if( !iter.hasNext() )
- Nil
- else
- (iter.next().asInstanceOf[a])::iterToList( iter ) ;
+ class GenericFactoryAdapter extends FactoryAdapter() {
def elementContainsText( name:java.lang.String ):boolean = true;
// default behaviour is hash-consing
val cache = new HashMap();
- def createElement( elemName:String,
- attribs :java.util.Map, // ignore attributes.
- children:java.util.Iterator ):scala.Object = {
+ def createElement( elemName: String,
+ attrs: java.util.Map,
+ children: java.util.Iterator ):scala.Object = {
+
+ val el = new Labelled( Symbol( elemName ),
+ Generic.iterToList[ Any ]( children ))
+ with Attribbed {
+ def attribs = Generic.mapToMap[String,String]( attrs );
+ };
- val el = Labelled( Symbol( elemName), iterToList[ Any ]( children ));
- val el_cache = cache.get( el.asInstanceOf[scala.All]).asInstanceOf[scala.Object];
+ val el_cache = cache.get( el.asInstanceOf[scala.All])
+ .asInstanceOf[scala.Object];
if ( el_cache != null ) {
System.err.println("[using cached elem!]");
el_cache
diff --git a/sources/scala/xml/PCDATA.scala b/sources/scala/xml/PCDATA.scala
index 70d849f3bf..5b9aa01c1a 100644
--- a/sources/scala/xml/PCDATA.scala
+++ b/sources/scala/xml/PCDATA.scala
@@ -12,7 +12,23 @@ case class PCDATA( content:String ) extends Element {
def getAttribs = error("PCDATA.getAttribs");
def setAttribs( m:Map[ String, String ] ):Unit = error("PCDATA.setAttribs");
- override def toXML:String = content;
+ override def toXML:String = {
+ // new java.util.StringBuffer !!crashes!!
+ val s = new StringBuffer();
+ var i = 0;
+ while( i < content.length() ) {
+ val c = content.charAt( i );
+ c match {
+ case '<' => s.append("&lt;");
+ case '>' => s.append("&gt;");
+ case '&' => s.append("&amp;");
+ case '"' => s.append("&quot;");
+ case _ => s.append( c );
+ }
+ i = i + 1;
+ }
+ s.toString();
+ }
override def hashCode() = content.hashCode();
override def toString() = "PCDATA("+content+")";
diff --git a/sources/scala/xml/ScalaFactoryAdapter.scala b/sources/scala/xml/ScalaFactoryAdapter.scala
index 2a777c6e38..600357b6cd 100644
--- a/sources/scala/xml/ScalaFactoryAdapter.scala
+++ b/sources/scala/xml/ScalaFactoryAdapter.scala
@@ -3,45 +3,23 @@ package scala.xml ;
import scala.xml.javaAdapter.Map ;
import scala.xml.javaAdapter.HashMap ;
-/** a Scala specific dtd2scala.FactoryAdapter, which plays the SAX content handler for the SAX parser
- * It implements the three callback methods elementContainsText, createElement and createPCDATA.
- * DTDs imported with the dtd2scala tool all use this class as interface to the SAX XML parser, by
- * giving concrete values for the factory maps f and g.
- */
+/** a Scala specific dtd2scala.FactoryAdapter, which plays the SAX content
+* handler for the SAX parser. It implements the three callback methods
+* elementContainsText, createElement and createPCDATA. DTDs imported with
+* the dtd2scala tool all use this class as interface to the SAX XML parser,
+* by giving concrete values for the factory maps f and g.
+*/
abstract class ScalaFactoryAdapter
extends FactoryAdapter() {
- def iterToList[ a ]( iter:java.util.Iterator ):List[a] =
- if( !iter.hasNext() )
- Nil
- else
- (iter.next().asInstanceOf[a])::iterToList( iter ) ;
-
-
- def mapToMap[a,b]( map:java.util.Map ):Map[a,b] = {
-
- val keys:java.util.Iterator = map.keySet().iterator();
- val res = new HashMap[a,b] ;
-
- def iterToMap:Unit =
- if( keys.hasNext() ) {
- val key = keys.next();
- val value = map.get( key ).asInstanceOf[b] ;
- res.put( key.asInstanceOf[a] , value.asInstanceOf[b] );
- iterToMap
- } else
- () ;
-
- iterToMap;
- res
- }
-
- /** a mapping from a element name (string) to an element constructor (constr:Seq[Element] => Element)
- */
+ /** a mapping from a element name (string) to an element constructor
+ * (constr:Seq[Element] => Element)
+ */
val f: Map[ String, Seq[Element] => Element ];
- /** a mapping from an element name (string) to a truth value indicating whether text (PCDATA) may appear as
+ /** a mapping from an element name (string) to a truth value indicating
+ * whether text (PCDATA) may appear as
*/
val g: Map[ String, boolean ] ;
@@ -57,11 +35,11 @@ abstract class ScalaFactoryAdapter
def createElement(elemName:String,
attribs:java.util.Map,
children:java.util.Iterator ):scala.Object = {
- val _children = iterToList[Element]( children ); // 2do:optimize
+ val _children = Generic.iterToList[Element]( children ); // 2do:optimize
if( !compress ) {
val c = f.get( elemName ); // get constructor
val el = c( _children );
- el.setAttribs( mapToMap[String,String]( attribs ) );
+ el.setAttribs( Generic.mapToMap[String,String]( attribs ) );
el
} else { // do hash-consing
@@ -72,7 +50,7 @@ abstract class ScalaFactoryAdapter
} else {
val c = f.get( elemName ); // get constructor
val el = c( _children );
- el.setAttribs( mapToMap[String,String]( attribs ) );
+ el.setAttribs( Generic.mapToMap[String,String]( attribs ) );
cache.put( h.asInstanceOf[scala.All], el.asInstanceOf[scala.All] );
el
}