From 6326ef9c7586f1197fb9ba1f30ce990aaf75ed50 Mon Sep 17 00:00:00 2001 From: "Justin Marsh (:flaviusb)" Date: Tue, 27 Jul 2010 17:28:57 +1200 Subject: [PATCH] Now we keep xmlns as fake attributes; this allows us to preserve order in the interleaved case. Still some problems with whitespace in the interleaved lists. --- src/constantscript.scala | 2 +- src/scala/xml/parsing/spaceparser.scala | 12 +++++-- src/scala/xml/xmlparser.scala | 48 ++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/constantscript.scala b/src/constantscript.scala index a5b4484..93a9c0c 100644 --- a/src/constantscript.scala +++ b/src/constantscript.scala @@ -146,7 +146,7 @@ object fixer { sb.append('<') x.nameToString(sb) if (x.attributes ne null) buildAttrString(x.attributes, sb) - buildNSString(x.scope, sb, pscope) + //buildNSString(x.scope, sb, pscope) if (x.scope != pscope) x.scope match { case ns: NamespaceBindingS => sb append ns.space diff --git a/src/scala/xml/parsing/spaceparser.scala b/src/scala/xml/parsing/spaceparser.scala index 868768a..2ae2c75 100644 --- a/src/scala/xml/parsing/spaceparser.scala +++ b/src/scala/xml/parsing/spaceparser.scala @@ -31,7 +31,11 @@ class SpaceParser(override val input: Source, override val preserveWS: Boolean) * [41] Attributes ::= { S Name Eq AttValue } */ def xAttributes2(pscope:NamespaceBinding): (MetaData,NamespaceBinding) = { - var scope: NamespaceBinding = pscope + var scope: NamespaceBindingS = if (pscope eq TopScope) TopScopeS else NamespaceBindingS(pscope.prefix, pscope.uri, pscope.parent) + xAttributes2(scope); + } + def xAttributes2(pscope:NamespaceBindingS): (MetaData,NamespaceBinding) = { + var scope: NamespaceBindingS = pscope var aMap: MetaData = Null if (isSpace(ch)) aMap = WhiteSpace(xSpaceS, aMap); @@ -46,15 +50,17 @@ class SpaceParser(override val input: Source, override val preserveWS: Boolean) case Some("xmlns") => val prefix = qname.substring(6 /*xmlns:*/ , qname.length); scope = new NamespaceBindingS(prefix, value, scope, space=(if(isSpace(ch)) {xSpaceS} else {""})); + aMap = WhiteSpace(scope.space, new fakePrefixedAttribute("xmlns", prefix, Text(value), aMap)); case Some(prefix) => val key = qname.substring(prefix.length+1, qname.length); aMap = new PrefixedAttribute(prefix, key, Text(value), aMap); case _ => - if( qname == "xmlns" ) + if( qname == "xmlns" ) { scope = new NamespaceBindingS(null, value, scope, space=(if(isSpace(ch)) {xSpaceS} else {""})); - else + aMap = WhiteSpace(scope.space, new fakeUnprefixedAttribute("xmlns", Text(value), aMap)) + } else aMap = new UnprefixedAttribute(qname, Text(value), aMap); } diff --git a/src/scala/xml/xmlparser.scala b/src/scala/xml/xmlparser.scala index d5e5c15..610278c 100644 --- a/src/scala/xml/xmlparser.scala +++ b/src/scala/xml/xmlparser.scala @@ -15,7 +15,29 @@ import annotation.tailrec //import Utility.{ isNameStart } -case class NamespaceBindingS(override val prefix: String, override val uri: String, override val parent: NamespaceBinding, space: String = " ") extends NamespaceBinding(prefix, uri, parent) { } +case class NamespaceBindingS(override val prefix: String, override val uri: String, override val parent: NamespaceBinding, space: String = " ") extends NamespaceBinding(prefix, uri, parent) { + override def getURI(_prefix: String): String = + if (prefix == _prefix) uri else { + if (parent == null) + { if (_prefix == "xml") "http://www.w3.org/XML/1998/namespace" else null: String } + else + parent getURI _prefix + } +} +// Need an analogous TopScopeS +case object TopScopeS extends NamespaceBindingS(null, null, null, "") { + import XML.{ xml, namespace } + + override def getURI(prefix1: String): String = + if (prefix1 == xml) namespace else null + + override def getPrefix(uri1: String): String = + if (uri1 == namespace) xml else null + + override def toString() = "" + override def buildString(stop: NamespaceBinding) = "" + override def buildString(sb: StringBuilder, ignore: NamespaceBinding) = {} +} /** Essentially, every method in here is a facade, delegating to next. * It provides a backstop for the unusual collection defined by MetaData, @@ -60,6 +82,30 @@ case class WhiteSpace(space: String, override val next: MetaData) extends MetaDa object WhiteSpace { def apply(space: String, next: WhiteSpace) = next } + +//Unroll what should be a duck punch for RTTI reasons; replaces attributes used for xmlns +class fakePrefixedAttribute( + override val pre: String, + override val key: String, + override val value: Seq[Node], + override val next: MetaData) extends PrefixedAttribute(pre, key, value, next) { + override def wellformed(scope: NamespaceBinding): Boolean = { + (next wellformed scope) + } + override def toString1(sb: StringBuilder): Unit = { } + override def toString1(): String = "" +} +class fakeUnprefixedAttribute( + override val key: String, + override val value: Seq[Node], + next1: MetaData) extends UnprefixedAttribute(key, value, next1) { + override def wellformed(scope: NamespaceBinding): Boolean = { + (next wellformed scope) + } + override def toString1(sb: StringBuilder): Unit = { } + override def toString1(): String = "" +} + trait whitespaceRootPatch { self: MetaData => /**