diff options
author | buraq <buraq@epfl.ch> | 2004-08-02 13:21:53 +0000 |
---|---|---|
committer | buraq <buraq@epfl.ch> | 2004-08-02 13:21:53 +0000 |
commit | 8ac6b339272befc95e4596c6c957b1316782439d (patch) | |
tree | a1219601533efc06ec770afaca896164ea94d5bb | |
parent | a14f094cf508d6f0cc0206165ff6514ee90c4dac (diff) | |
download | scala-8ac6b339272befc95e4596c6c957b1316782439d.tar.gz scala-8ac6b339272befc95e4596c6c957b1316782439d.tar.bz2 scala-8ac6b339272befc95e4596c6c957b1316782439d.zip |
modified xml parsing
4 files changed, 105 insertions, 59 deletions
diff --git a/sources/scala/tools/servlet/engine/config/ConfigHandler.scala b/sources/scala/tools/servlet/engine/config/ConfigHandler.scala index 537dbf6a0a..dcbd659866 100644 --- a/sources/scala/tools/servlet/engine/config/ConfigHandler.scala +++ b/sources/scala/tools/servlet/engine/config/ConfigHandler.scala @@ -15,18 +15,18 @@ class ConfigHandler extends MarkupHandler[Config] { def attributeNamespaceDecl(pos: int, uri: String) = NamespaceDecl(uri); - override def attribute(pos: int, key: String, value:String): AttribValue = + override def attribute(pos: int, uri:String, key: String, value:String): AttribValue = if( key == "port" ) attributeIntValue(pos, Integer.parseInt(value)); else - super.attribute(pos,key,value); + super.attribute(pos, uri, key, value); var hmap = new mutable.HashMap[String,String]; /** be careful to copy everything from attrMap1, as it will change * @param attrMap1 the attribute map. */ - def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[String,AttribValue], args: mutable.Buffer[Config]): Option[Config] = { + def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[Pair[String,String],AttribValue], args: mutable.Buffer[Config]): Option[Config] = { if( uri == config_namespace ) { label match { @@ -39,13 +39,13 @@ class ConfigHandler extends MarkupHandler[Config] { } Some(EngineConfig( list )); - case "connector" if attrMap1("protocol").asString == "http" => - val res = HttpConnectorConfig( attrMap1("port").asInt, hmap ); + case "connector" if attrMap1(Pair(config_namespace,"protocol")).asString == "http" => + val res = HttpConnectorConfig( attrMap1(Pair(config_namespace,"port")).asInt, hmap ); hmap = new mutable.HashMap[String,String]; Some(res) case "map" => - hmap.update(attrMap1("url").asString, attrMap1("to").asString); + hmap.update(attrMap1(Pair(config_namespace,"url")).asString, attrMap1(Pair(config_namespace,"to")).asString); None } } else None diff --git a/sources/scala/xml/parsing/ConstructingHandler.scala b/sources/scala/xml/parsing/ConstructingHandler.scala index f58dac7b21..dcbf0d7d28 100644 --- a/sources/scala/xml/parsing/ConstructingHandler.scala +++ b/sources/scala/xml/parsing/ConstructingHandler.scala @@ -10,16 +10,16 @@ class ConstructingHandler extends MarkupHandler[Node] { def attributeNamespaceDecl(pos: int, uri: String) = NamespaceDecl(uri); - def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[String,AttribValue], args: mutable.Buffer[Node]) = { + def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[Pair[String,String],AttribValue], args: mutable.Buffer[Node]) = { var attrs = new Array[Attribute](attrMap1.size); { var i = 0; val it = attrMap1.elements; while( it.hasNext ) { - val Pair(ke:String, va: AttribValue) = it.next; + val Pair(Pair(uri:String, key:String), va: AttribValue) = it.next; va match { - case CDataValue(str) => attrs( i ) = Attribute("",ke,str); + case CDataValue(str) => attrs( i ) = Attribute(uri, key, str); } i = i + 1; } diff --git a/sources/scala/xml/parsing/MarkupHandler.scala b/sources/scala/xml/parsing/MarkupHandler.scala index 945f053a8e..ced3895035 100644 --- a/sources/scala/xml/parsing/MarkupHandler.scala +++ b/sources/scala/xml/parsing/MarkupHandler.scala @@ -5,7 +5,7 @@ import scala.collection.mutable ; import scala.collection.Map ; /** class that handles markup - provides callback methods to MarkupParser */ -abstract class MarkupHandler[MarkupType] { +abstract class MarkupHandler[A] { /** a stack of prefix namespace mappings */ protected val prefixStack = @@ -13,7 +13,13 @@ abstract class MarkupHandler[MarkupType] { /** mapping from prefixes to namespaces */ var namespace: immutable.Map[String,String] = - new immutable.TreeMap[String,String].update("",""); + new immutable.TreeMap[String,String] + .update("","") + .update("xml","http://www.w3.org/XML/1998/namespace"); + + + var tmpPrefix: mutable.Map[String, String] = + new mutable.HashMap[String,String]; /** returns prefix of the qualified name if any */ final def namespacePrefix(name: String): Option[String] = { @@ -23,10 +29,10 @@ abstract class MarkupHandler[MarkupType] { /** removes xmlns attributes from attr as a side effect, and returns a prefix * map resulting from them - */ - final def namespaceDecl(aMap: mutable.Map[String, AttribValue]): Map[String, String] = { + * / + final def namespaceDecl1(aMap: mutable.Map[String, AttribValue]): Map[String, String] = { val setNS = new mutable.HashMap[String, String]; - /* DEBUG */ + / * DEBUG * / val attrIt = aMap.keys; while( attrIt.hasNext ) { val z = attrIt.next; @@ -47,40 +53,46 @@ abstract class MarkupHandler[MarkupType] { } setNS; } + */ + + /** removes xmlns attributes from attr as a side effect, and returns a prefix + * map resulting from them + */ + final def internal_namespaceDecl(prefix:String, uri:String): Unit = { + tmpPrefix.update(prefix, uri); + } def attributeCDataValue(pos: int, str:String): AttribValue; def attributeNamespaceDecl(pos: int, uri: String): AttribValue; - def attribute(pos: int, key: String, value:String): AttribValue = - if( key.startsWith("xmlns")) - attributeNamespaceDecl(pos, value); - else - attributeCDataValue(pos, value); + def attribute(pos: int, uri: String, key: String, value:String): AttribValue = + attributeCDataValue(pos, value); /** be careful to copy everything from attrMap1, as it will change - * @param attrMap1 the attribute map. + * @param pos the position in the sourcefile + * @param uri the namespace uri + * @param label the tag name + * @param attrMap1 the attribute map, from Pair(uri,label) to target + * @param args the children of this element */ - def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[String,AttribValue], args: mutable.Buffer[MarkupType]): Iterable[MarkupType]; + def element(pos: int, uri: String, label: String, attrMap1: mutable.Map[Pair[String,String],AttribValue], args: mutable.Buffer[A]): Iterable[A]; - def charData(pos: Int, txt: String ): Iterable[MarkupType]; - def procInstr(pos: Int, target: String, txt: String): Iterable[MarkupType]; - def comment(pos: Int, comment: String ): Iterable[MarkupType]; - def entityRef(pos: Int, n: String): Iterable[MarkupType]; + def charData(pos: Int, txt: String ): Iterable[A]; + def procInstr(pos: Int, target: String, txt: String): Iterable[A]; + def comment(pos: Int, comment: String ): Iterable[A]; + def entityRef(pos: Int, n: String): Iterable[A]; - def text(pos: Int, txt:String): Iterable[MarkupType]; + def text(pos: Int, txt:String): Iterable[A]; - def internal_startPrefixMapping(pref: Map[String, String]) = { - if( !pref.isEmpty ) { - this.prefixStack.push( this.namespace ); - this.namespace = this.namespace incl pref; - } + def internal_startPrefixMapping: Unit = { + this.prefixStack.push( this.namespace ); + this.namespace = this.namespace incl tmpPrefix; + tmpPrefix.clear; } - def internal_endPrefixMapping(pref: Map[String, String]): Unit = { - if( !pref.isEmpty ) { - this.namespace = prefixStack.pop; - } + def internal_endPrefixMapping: Unit = { + this.namespace = prefixStack.pop; } } diff --git a/sources/scala/xml/parsing/MarkupParser.scala b/sources/scala/xml/parsing/MarkupParser.scala index bab7a5b67e..ab62a37dc7 100644 --- a/sources/scala/xml/parsing/MarkupParser.scala +++ b/sources/scala/xml/parsing/MarkupParser.scala @@ -42,7 +42,7 @@ abstract class MarkupParser[MarkupType] { protected var aMap: mutable.Map[String,AttribValue] = _; final val noChildren = new mutable.ListBuffer[MarkupType]; - final val noAttribs = new mutable.HashMap[String, AttribValue]; + final val noAttribs = new mutable.HashMap[Pair[String,String], AttribValue]; //var xEmbeddedBlock = false; @@ -84,33 +84,66 @@ abstract class MarkupParser[MarkupType] { * | `{` scalablock `}` */ def xAttributes = { - val aMap = new mutable.HashMap[String,AttribValue]; + val aMap = new mutable.HashMap[Pair[String,String],Pair[Int,String]]; while( xml.Parsing.isNameStart( ch )) { - val key = xName; + val pos = this.pos; + val key1 = xName; + var prefix: String = _; + var key: String = _; + + handle.namespacePrefix(key1) match { + case Some(x @ "xmlns") => + prefix = null; + key = key1.substring(x.length()+1, key1.length()); + case Some(x) => + prefix = x; + key = key1.substring(x.length()+1, key1.length()); + case _ => + if( key1 == "xmlns" ) { + prefix= null; + key = ""; + } else { + prefix = ""; + key = key1 + } + } xEQ; val delim = ch; val pos1 = pos; - val value:AttribValue = ch match { + val value:String = ch match { case '"' | '\'' => nextch; val tmp = xAttributeValue(delim); nextch; - handle.attribute( pos1, key, tmp ); - /*case '{' if enableEmbeddedExpressions => - nextch; - handle.attributeEmbedded(pos1, xEmbeddedExpr);*/ + tmp; case _ => - reportSyntaxError( "' or \" delimited attribute value or '{' scala-expr '}' expected" ); - handle.attribute( pos1, key, "<syntax-error>" ) + reportSyntaxError( "' or \" delimited attribute value expected" ); + "<syntax-error>" }; - // well-formedness constraint: unique attribute names - if (aMap.contains(key)) - reportSyntaxError( "attribute " + key + " may only be defined once" ); - aMap.update( key, value ); + + if(prefix == null) { + handle.internal_namespaceDecl(key, value); + } else { + aMap.update( Pair(prefix,key), Pair(pos,value) ); + } + if ((ch != '/') && (ch != '>')) xSpace; - }; - aMap + } + // @todo, iterate over attributes, replace prefix, call handleAttribute. + handle.internal_startPrefixMapping; + val aMap1 = new mutable.HashMap[Pair[String,String],AttribValue]; + val it = aMap.elements; + while( it.hasNext ) { + val x @ Pair(Pair(pref,key),Pair(pos,value)) = it.next; + val uri = handle.namespace(pref); + val qkey = Pair(uri, key); + // well-formedness constraint: unique attribute names + if (aMap.contains(qkey)) + reportSyntaxError( "attribute " + key + " may only be defined once" ); + aMap1.update(qkey, handle.attribute(pos, uri, key, value)); + } + aMap1 } /** attribute value, terminated by either ' or ". value may not contain <. @@ -136,15 +169,16 @@ abstract class MarkupParser[MarkupType] { * [40] STag ::= '<' Name { S Attribute } [S] * [44] EmptyElemTag ::= '<' Name { S Attribute } [S] */ - protected def xTag: Pair[String, mutable.Map[String,AttribValue]] = { + protected def xTag: Pair[String, mutable.Map[Pair[String,String],AttribValue]] = { val elemqName = xName; xSpaceOpt; - val aMap: mutable.Map[String,AttribValue] = + val aMap: mutable.Map[Pair[String,String],AttribValue] = if(xml.Parsing.isNameStart( ch )) { xAttributes; } else { - noAttribs + handle.internal_startPrefixMapping; + noAttribs; }; Pair(elemqName, aMap); } @@ -318,13 +352,13 @@ abstract class MarkupParser[MarkupType] { if(ch == '/') { // empty element xToken('/'); xToken('>'); - pref = handle.namespaceDecl( aMap ); - handle.internal_startPrefixMapping( pref ); + //pref = handle.namespaceDecl( aMap ); + //handle.internal_startPrefixMapping( pref ); noChildren; } else { // element with content xToken('>'); - pref = handle.namespaceDecl( aMap ); - handle.internal_startPrefixMapping( pref ); + //pref = handle.namespaceDecl( aMap ); + //handle.internal_startPrefixMapping( pref ); val tmp = content; xEndTag( qname ); tmp; @@ -339,7 +373,7 @@ abstract class MarkupParser[MarkupType] { handle.namespace(""); } val res = handle.element(pos1, uri, name, aMap, ts ); - handle.internal_endPrefixMapping( pref ); + handle.internal_endPrefixMapping; res } |