From 470f990722777041a475de2e5cf02ca4504a2237 Mon Sep 17 00:00:00 2001 From: Burak Emir Date: Sat, 14 Oct 2006 13:31:12 +0000 Subject: xml improvements for 2.2.1 (see changes) --- docs/examples/xml/phonebook/embeddedBook.scala | 26 ++++++ docs/examples/xml/phonebook/phonebook.scala | 38 +++++++++ docs/examples/xml/phonebook/phonebook1.scala | 21 +++++ docs/examples/xml/phonebook/phonebook2.scala | 25 ++++++ docs/examples/xml/phonebook/phonebook3.scala | 96 ++++++++++++++++++++++ docs/examples/xml/phonebook/verboseBook.scala | 24 ++++++ .../scala/tools/nsc/ast/TreePrinters.scala | 2 +- .../scala/tools/nsc/ast/parser/MarkupParsers.scala | 48 +++++++++-- .../tools/nsc/ast/parser/SymbolicXMLBuilder.scala | 38 +++++++-- src/library/scala/xml/Group.scala | 1 + src/library/scala/xml/PrettyPrinter.scala | 1 + src/library/scala/xml/UnprefixedAttribute.scala | 2 +- src/library/scala/xml/Utility.scala | 43 +++++++--- test/files/jvm/xml01.check | 3 + test/files/jvm/xml01.scala | 9 ++ test/files/jvm/xml02.scala | 3 +- test/files/jvm/xmlattr.check | 2 + test/files/jvm/xmlattr.scala | 6 ++ test/files/run/unittest_xml.scala | 55 +++++++++++++ 19 files changed, 416 insertions(+), 27 deletions(-) create mode 100644 docs/examples/xml/phonebook/embeddedBook.scala create mode 100644 docs/examples/xml/phonebook/phonebook.scala create mode 100644 docs/examples/xml/phonebook/phonebook1.scala create mode 100644 docs/examples/xml/phonebook/phonebook2.scala create mode 100644 docs/examples/xml/phonebook/phonebook3.scala create mode 100644 docs/examples/xml/phonebook/verboseBook.scala create mode 100644 test/files/run/unittest_xml.scala diff --git a/docs/examples/xml/phonebook/embeddedBook.scala b/docs/examples/xml/phonebook/embeddedBook.scala new file mode 100644 index 0000000000..8ea9628212 --- /dev/null +++ b/docs/examples/xml/phonebook/embeddedBook.scala @@ -0,0 +1,26 @@ +/* examples/phonebook/embeddedBook.scala */ +package phonebook + +object embeddedBook { + + val company = ACME + val first = "Burak" + val last = "Emir" + val location = "work" + + val embBook = + + + This is the phonebook of the + {company} corporation. + + + { first+" "+last } + +41 21 693 68 {val x = 60 + 7; x} + + ; + + def main(args: Array[String]) = + Console.println( embBook ) + +} diff --git a/docs/examples/xml/phonebook/phonebook.scala b/docs/examples/xml/phonebook/phonebook.scala new file mode 100644 index 0000000000..4813c2d20d --- /dev/null +++ b/docs/examples/xml/phonebook/phonebook.scala @@ -0,0 +1,38 @@ +package phonebook ; + +object phonebook { + + val labPhoneBook = + + + This is the phonebook of the + ACME corporation. + + + Burak + +41 21 693 68 67 + +41 79 602 23 23 + + ; + + Console.println( labPhoneBook ); + + // XML is immutable - adding an element + + import scala.xml.{ Node, Text }; + + def add( phonebook:Node, newEntry:Node ):Node = phonebook match { + case { ch @ _* } => + { ch }{ newEntry } + } + + val pb2 = + add( labPhoneBook, + + Kim + +41 21 111 11 11 + ); + + def main(args:Array[String]) = Console.println( pb2 ); + +} diff --git a/docs/examples/xml/phonebook/phonebook1.scala b/docs/examples/xml/phonebook/phonebook1.scala new file mode 100644 index 0000000000..3a7a165202 --- /dev/null +++ b/docs/examples/xml/phonebook/phonebook1.scala @@ -0,0 +1,21 @@ +/* examples/phonebook/phonebook1.scala */ +package phonebook + +object phonebook1 { + + val labPhoneBook = + + + This is the phonebook of the + ACME corporation. + + + Burak Emir + +41 21 693 68 67 + + ; + + def main(args: Array[String]) = + Console.println( labPhoneBook ) + +} diff --git a/docs/examples/xml/phonebook/phonebook2.scala b/docs/examples/xml/phonebook/phonebook2.scala new file mode 100644 index 0000000000..ba50379369 --- /dev/null +++ b/docs/examples/xml/phonebook/phonebook2.scala @@ -0,0 +1,25 @@ +/* examples/xml/phonebook/phonebook2.scala */ +package phonebook; + +object phonebook2 { + + import scala.xml.Node + + /** adds an entry to a phonebook */ + def add( p: Node, newEntry: Node ): Node = p match { + + case { ch @ _* } => + + { ch }{ newEntry } + } + + val pb2 = + add( phonebook1.labPhoneBook, + + Kim + +41 21 111 11 11 + ); + + def main( args: Array[String] ) = + Console.println( pb2 ) +} diff --git a/docs/examples/xml/phonebook/phonebook3.scala b/docs/examples/xml/phonebook/phonebook3.scala new file mode 100644 index 0000000000..ec49d450f4 --- /dev/null +++ b/docs/examples/xml/phonebook/phonebook3.scala @@ -0,0 +1,96 @@ +/* examples/xml/phonebook/phonebook3.scala */ +package phonebook + +object phonebook3 { + + import scala.xml.{Elem, Node, Text} + import scala.xml.Utility.view + import scala.xml.PrettyPrinter + import Node.NoAttributes + + /* finds entry for Name, Where, changes it, or adds if not present */ + def change ( phonebook: Node, Name: String, Where: String, newPhone: String ) = { + + /** returns true if this element's first child is the right 'name' + * x is treated a if it was a singleton sequence here. + */ + def hasName ( x: Seq[Node] ) = x(0).child.elements.next match { + case { Text(Name) } => true + case _ => false + } + + /** returns true if this element has the right 'where' attribute + * y is treated a if it was a singleton sequence here. + * n.attribute(s) is the same as n.attributes.get(s) + */ + def hasWhere ( y: Node ) = y.attribute("where") match { + case Some(Text(Where)) => true + case None => false + } + + /** returns true if this element has the right 'where' attribute + * the apply method of MetaData (n.attributes) returns raw a + * sequence of nodes. + */ + def hasWhere2 ( y: Node ) = y.attributes("where") match { + case null => false + case Text(Where) => true + case _ => false + } + + + /** walks through tree, returns changed/copied updated tree */ + def copyOrChange ( ch: Iterator[Node] ):List[Node] = { + for( val c <- ch ) yield c match { + + case x @ { ch1 @ _* } if hasName( x ) => + val it = ch1.elements; + val nameElem:Seq[Node] = it.next; // grab 'name' element + val ch2 = nameElem concat copyOrChange( it ); // concat with updated seq + + if( ch1 == ch2 ) // not present: add as first entry + + + { Name } + { newPhone } + { ch1 } + + + else // was present and changed + + + { ch2 } + + + case y @ { _* } if hasWhere( y ) => + Console.println("c = "+c); + { newPhone } + + case _ => + Console.println("c = "+c); + Console.println("c.attributes= "+c.attributes); + c + + } + }.toList ; // for ... yield ... returns Iterator, convert to list + + // decompose phonebook, apply updates + phonebook match { + case { ch @ _* } => + { copyOrChange( ch.elements ) } + } + + } + + val pb2 = + change( phonebook1.labPhoneBook, "John", "work", "+41 55 555 55 55" ); + + val pp = new PrettyPrinter( 80, 5 ); + + def main( args:Array[String] ) = { + Console.println("---before---"); + Console.println( pp.format( phonebook1.labPhoneBook )); + Console.println("---after---"); + Console.println( pp.format( pb2 )); + } +} diff --git a/docs/examples/xml/phonebook/verboseBook.scala b/docs/examples/xml/phonebook/verboseBook.scala new file mode 100644 index 0000000000..611cf5370e --- /dev/null +++ b/docs/examples/xml/phonebook/verboseBook.scala @@ -0,0 +1,24 @@ +/* examples/xml/phonebook/verboseBook.scala */ +package phonebook + +object verboseBook { + + import scala.xml.{ UnprefixedAttribute, Elem, Node, Null, Text, TopScope } + + val pbookVerbose = + Elem(null, "phonebook", Null, TopScope, + Elem(null, "descr", Null, TopScope, + Text("This is a "), + Elem(null, "b", Null, TopScope, Text("sample")), + Text("description") + ), + Elem(null, "entry", Null, TopScope, + Elem(null, "name", Null, TopScope, Text("Burak Emir")), + Elem(null, "phone", new UnprefixedAttribute("where","work", Null), TopScope, + Text("+41 21 693 68 67")) + ) + ) + + def main(args: Array[String]) = + Console.println( pbookVerbose ) +} diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 916736bda4..9f9ce71c7e 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -280,7 +280,7 @@ abstract class TreePrinters { print("this") case Select(qual @ New(tpe), name) => - assert(tree.symbol == null || tree.symbol.isConstructor) + assert(tree.symbol == null || tree.symbol.isConstructor || phase.prev.name == "parser") print(qual) case Select(qualifier, name) => diff --git a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala index f2e31ed6ce..0adf872a81 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/MarkupParsers.scala @@ -91,7 +91,14 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean nextch val tmp = xAttributeValue(delim) nextch - Literal(Constant(tmp)) + try { + handle.parseAttribute(pos1, tmp) + } catch { + case e => + reportSyntaxError("error parsing attribute value") + p.errorTermTree + } + case '{' => nextch xEmbeddedExpr @@ -181,6 +188,34 @@ class MarkupParser(unit: CompilationUnit, s: Scanner, p: Parser, presWS: boolean Predef.error("this cannot happen") } + def xUnparsed: Tree = { + val pos1 = pos + val sb: StringBuffer = new StringBuffer() + while (true) { + if (ch=='<' && + { sb.append(ch); nextch; ch == '/' } && + { sb.append(ch); nextch; ch == 'x' } && + { sb.append(ch); nextch; ch == 'm' } && + { sb.append(ch); nextch; ch == 'l' } && + { sb.append(ch); nextch; ch == ':' } && + { sb.append(ch); nextch; ch == 'u' } && + { sb.append(ch); nextch; ch == 'n' } && + { sb.append(ch); nextch; ch == 'p' } && + { sb.append(ch); nextch; ch == 'a' } && + { sb.append(ch); nextch; ch == 'r' } && + { sb.append(ch); nextch; ch == 's' } && + { sb.append(ch); nextch; ch == 'e' } && + { sb.append(ch); nextch; ch == 'd' } && + { sb.append(ch); nextch; ch == '>' }) { + sb.setLength(sb.length - "') + if(qname == "xml:unparsed") + return xUnparsed + debugLastStartElement.push(Pair(pos1, qname)) val ts = content xEndTag(qname) debugLastStartElement.pop - if(qname=="xml:group") - handle.group(pos1, ts) - else - handle.element(pos1, qname, attrMap, ts) + qname match { + case "xml:group" => handle.group(pos1, ts) + case _ => handle.element(pos1, qname, attrMap, ts) + } } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala index 3a14035312..1d6b1319a7 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala @@ -9,7 +9,7 @@ package scala.tools.nsc.ast.parser import scala.collection.immutable.{Map, ListMap} import scala.collection.mutable import scala.tools.nsc.util.Position -import scala.xml.{Text, TextBuffer} +import scala.xml.{EntityRef, Text, TextBuffer} import symtab.Flags.MUTABLE /** This class builds instance of Tree that represent XML. @@ -37,6 +37,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser def _UnprefixedAttribute = global.newTypeName("UnprefixedAttribute") def _Elem = global.newTypeName("Elem") def _Group = global.newTypeName("Group") + def _Unparsed = global.newTypeName("Unparsed") def _Seq = global.newTypeName("Seq") def _immutable = global.newTermName("immutable") def _mutable = global.newTermName("mutable") @@ -79,6 +80,7 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser private def _scala_xml_Elem = _scala_xml(_Elem) private def _scala_xml_Attribute = _scala_xml(_Attribute) private def _scala_xml_Group = _scala_xml(_Group) + private def _scala_xml_Unparsed = _scala_xml(_Unparsed) /* private def bufferToArray(buf: mutable.Buffer[Tree]): Array[Tree] = { @@ -99,11 +101,10 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser protected def mkXML(pos: int, isPattern: boolean, pre: Tree, label: Tree, attrs: /*Array[*/Tree/*]*/ , scope:Tree, children: mutable.Buffer[Tree]): Tree = { if (isPattern) { - //val ts = new mutable.ArrayBuffer[Tree]() convertToTextPat(children) - atPos (pos) { + atPos (pos) { //@todo maybe matching on attributes, scope? Apply( _scala_xml_Elem, List( - pre, label, Ident( nme.WILDCARD ) /* attributes? */ , Ident( nme.WILDCARD )) /* scope? */ ::: children.toList ) + pre, label, Ident( nme.WILDCARD ) /* md */ , Ident( nme.WILDCARD )) /* scope */ ::: children.toList ) } } else { var ab = List(pre, label, attrs, scope); @@ -167,6 +168,20 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser case _ => t } + def parseAttribute(pos: Int, s: String): Tree = { + val ns = xml.Utility.parseAttributeValue(s) + val ts:collection.mutable.ListBuffer[Tree] = new collection.mutable.ListBuffer + val it = ns.elements + while(it.hasNext) it.next match { + case Text(s) => ts += text(pos, s) // makeText1(Literal(Constant(s))) + case EntityRef(s) => ts += entityRef(pos, s) + } + ts.length match { + case 0 => gen.mkNil + case 1 => val t = ts(0); ts.clear; t + case _ => makeXMLseq(pos, ts) + } + } protected def convertToTextPat(buf: mutable.Buffer[Tree]): Unit = { var i = 0; while (i < buf.length) { val t1 = buf(i) @@ -208,6 +223,12 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser atPos(pos) { New( _scala_xml_Group, LL( makeXMLseq(pos, args))) } } + /** code that constructs an unparsed node + */ + def unparsed(pos: int, str: String): Tree = { + atPos(pos) { New( _scala_xml_Unparsed, LL( Literal(Constant(str)))) } + } + /** makes an element */ def element(pos: int, qname: String, attrMap: mutable.Map[String,Tree], args: mutable.Buffer[Tree]): Tree = { //Console.println("SymbolicXMLBuilder::element("+pos+","+qname+","+attrMap+","+args+")"); @@ -216,10 +237,11 @@ abstract class SymbolicXMLBuilder(make: TreeBuilder, p: Parsers # Parser, preser var tlist: List[Tree] = List() /* pre can be null */ - def handleNamespaceBinding(pre:String , uri:Tree): Unit = { - val t = Assign(Ident(_tmpscope), New( _scala_xml_NamespaceBinding, - LL(Literal(Constant(pre)), uri, Ident( _tmpscope)))); - tlist = t :: tlist + def handleNamespaceBinding(pre:String , uri1: Tree): Unit = uri1 match { + case Apply(_,List(uri @ Literal(Constant(_)))) => //text + val t = Assign(Ident(_tmpscope), New( _scala_xml_NamespaceBinding, + LL(Literal(Constant(pre)), uri, Ident( _tmpscope)))); + tlist = t :: tlist //Console.println("SymbolicXMLBuilder::handleNamespaceBinding:"); //Console.println(t.toString()); } diff --git a/src/library/scala/xml/Group.scala b/src/library/scala/xml/Group.scala index c5f7911138..7ca864add7 100644 --- a/src/library/scala/xml/Group.scala +++ b/src/library/scala/xml/Group.scala @@ -25,6 +25,7 @@ case class Group(val nodes: Seq[Node]) extends Node { /** structural equality */ override def equals(x: Any) = x match { + case z:Group => (length == z.length) && sameElements(z) case z:Node => (length == 1) && z == apply(0) case z:Seq[Node] => sameElements(z) case z:String => text == z diff --git a/src/library/scala/xml/PrettyPrinter.scala b/src/library/scala/xml/PrettyPrinter.scala index cd146ddd58..7ef542cbb6 100644 --- a/src/library/scala/xml/PrettyPrinter.scala +++ b/src/library/scala/xml/PrettyPrinter.scala @@ -196,6 +196,7 @@ class PrettyPrinter( width:Int, step:Int ) { makeBreak() traverse(node.child.elements, node.scope, ind + step) makeBox(cur, etg) + makeBreak() } else { // give up makeBox(ind, test) makeBreak() diff --git a/src/library/scala/xml/UnprefixedAttribute.scala b/src/library/scala/xml/UnprefixedAttribute.scala index cc5d002e84..5159c5a67f 100644 --- a/src/library/scala/xml/UnprefixedAttribute.scala +++ b/src/library/scala/xml/UnprefixedAttribute.scala @@ -22,7 +22,7 @@ class UnprefixedAttribute(val key: String, val value: Seq[Node], next1: MetaData /** same as this(key, Utility.parseAttributeValue(value), next) */ def this(key: String, value: String, next: MetaData) = - this(key, if(value!=null) Utility.parseAttributeValue(value) else {val z:NodeSeq=null;z}, next) + this(key, if(value!=null) Text(value) else {val z:NodeSeq=null;z}, next) /** returns a copy of this unprefixed attribute with the given next field*/ def copy(next: MetaData) = diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index ffa2cdfc03..dd189360cb 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -33,11 +33,25 @@ object Utility extends AnyRef with parsing.TokenTests { case '>' => s.append(">") case '&' => s.append("&") case '"' => s.append(""") + case '\'' => s.append("'") case _ => s.append(c) } s } + /* appends unescaped string to s, amp becomes & lt becomes < + * @returns null if ref was not a predefined entity + */ + final def unescape(ref: String, s: StringBuilder): StringBuilder = + ref match { + case "lt" => s.append('<') + case "gt" => s.append('>') + case "amp" => s.append('&') + case "quot" => s.append('"') + case "apos" => s.append(''') + case _ => null + } + /** * Returns a set of all namespaces used in a sequence of nodes * and all their descendants, including the empty namespaces. @@ -265,17 +279,14 @@ object Utility extends AnyRef with parsing.TokenTests { */ def parseAttributeValue(value:String):Seq[Node] = { val zs:Seq[Char] = value - val sb = new StringBuilder() + val sb = new StringBuilder + var rfb: StringBuilder = null val nb = new NodeBuffer() val it = zs.elements while(it.hasNext) { var c = it.next c match { - case '&' => - if(sb.length() > 0) { - nb += Text(sb.toString()) - sb.setLength(0) - } + case '&' => // entity! flush buffer into text node it.next match { case '#' => c = it.next @@ -283,20 +294,30 @@ object Utility extends AnyRef with parsing.TokenTests { sb.append(theChar) case x => - sb.append(x) + if(rfb==null) rfb = new StringBuilder() + rfb.append(x) c = it.next while(c != ';') { - sb.append(c) + rfb.append(c) c = it.next } - nb += EntityRef(sb.toString()) - sb.setLength(0) + val ref = rfb.toString() + rfb.setLength(0) + unescape(ref,sb) match { + case null => + if(sb.length() > 0) { // flush buffer + nb += Text(sb.toString()) + sb.setLength(0) + } + nb += EntityRef(sb.toString()) // add entityref + case _ => + } } case x => sb.append(x) } } - if(sb.length() > 0) { + if(sb.length() > 0) { // flush buffer val x = Text(sb.toString()) if(nb.length == 0) return x diff --git a/test/files/jvm/xml01.check b/test/files/jvm/xml01.check index 5e9ee2aed0..2a8d2e5625 100644 --- a/test/files/jvm/xml01.check +++ b/test/files/jvm/xml01.check @@ -22,6 +22,9 @@ passed ok -- group nodes +passed ok +passed ok +passed ok attribute value normalization passed ok passed ok diff --git a/test/files/jvm/xml01.scala b/test/files/jvm/xml01.scala index 3558d95100..8c99cfd358 100644 --- a/test/files/jvm/xml01.scala +++ b/test/files/jvm/xml01.scala @@ -189,6 +189,15 @@ object Test { val zx2: Node = Group { List(,zy1,zx1) } Console println zx2.toString() + val zz1 = + + assertTrue(zx1 == zz1) + assertTrue(zz1.length == 3) + + // unparsed + + val uup = &<<>""^%@$!# + assertTrue(uup == "&<<>\"\"^%@$!#") // test unicode escapes backslash u Console println ("attribute value normalization"); diff --git a/test/files/jvm/xml02.scala b/test/files/jvm/xml02.scala index cbc9b5041b..d0d97e64eb 100644 --- a/test/files/jvm/xml02.scala +++ b/test/files/jvm/xml02.scala @@ -21,7 +21,8 @@ def main(args:Array[String]) = { Console.println("three"); assertEquals(bx \ "@foo", "bar&x") Console.println("four"); - assertSameElements(bx \ "@foo", List(xml.Text("bar"),xml.EntityRef("amp"),xml.Text("x"))) + assertSameElements(bx \ "@foo", List(xml.Text("bar&x"))) + //assertSameElements(bx \ "@foo", List(xml.Text("bar"),xml.EntityRef("amp"),xml.Text("x"))) Console.println("five"); assertEquals(bx.toString, "") diff --git a/test/files/jvm/xmlattr.check b/test/files/jvm/xmlattr.check index a1841a78ef..bebcb45081 100644 --- a/test/files/jvm/xmlattr.check +++ b/test/files/jvm/xmlattr.check @@ -8,3 +8,5 @@ true None null + + diff --git a/test/files/jvm/xmlattr.scala b/test/files/jvm/xmlattr.scala index 9801e05357..c34f66eafc 100644 --- a/test/files/jvm/xmlattr.scala +++ b/test/files/jvm/xmlattr.scala @@ -20,4 +20,10 @@ object Test extends Application { Console.println(x.get("foo")) // None Console.println(x("foo")) // null } + + val x1 = + val x2 = + Console.println(x1) + Console.println(x2) + } diff --git a/test/files/run/unittest_xml.scala b/test/files/run/unittest_xml.scala new file mode 100644 index 0000000000..5f7c523996 --- /dev/null +++ b/test/files/run/unittest_xml.scala @@ -0,0 +1,55 @@ + +object Test { + + import scala.testing.SUnit._ + import scala.xml.{MetaData, Null, PrefixedAttribute, UnprefixedAttribute } + + class MetaDataTest extends TestCase("collection.mutable.ArrayBuffer") with Assert { + + import scala.xml.{TopScope, NamespaceBinding, Atom, Text } + + override def runTest = { + + var x: MetaData = Null + var s: NamespaceBinding = TopScope + + // testing method def apply(uri:String, scp:NamespaceBinding, k:String): Seq[Node] + // def apply(k:String): Seq[Node] + + assertEquals("absent element (prefixed) 1", null, x("za://foo.com", s, "bar" )) + assertEquals("absent element (unprefix) 1", null, x("bar")) + + assertEquals("absent element (prefixed) 2", None, x.get("za://foo.com", s, "bar" )) + assertEquals("absent element (unprefix) 2", None, x.get("bar")) + + x = new PrefixedAttribute("zo","bar", new Atom(42), x) + s = new NamespaceBinding("zo","za://foo.com",s) + + assertEquals("present element (prefixed) 3", new Atom(42), x("za://foo.com", s, "bar" )) + assertEquals("present element (unprefix) 3", null, x("bar")) + + assertEquals("present element (prefixed) 4", Some(new Atom(42)), x.get("za://foo.com", s, "bar" )) + assertEquals("present element (unprefix) 4", None, x.get("bar")) + + x = new UnprefixedAttribute("bar","meaning", x) + + assertEquals("present element (prefixed) 5", null, x(null, s, "bar" )) + assertEquals("present element (unprefix) 5", Text("meaning"), x("bar")) + + assertEquals("present element (prefixed) 6", None, x.get(null, s, "bar" )) + assertEquals("present element (unprefix) 6", Some(Text("meaning")), x.get("bar")) + + } + } + + def main(args:Array[String]) = { + val ts = new TestSuite( + new MetaDataTest //, + ) + val tr = new TestResult() + ts.run(tr) + for(val failure <- tr.failures) { + Console.println(failure) + } + } +} -- cgit v1.2.3