]> dev.renevier.net Git - syp.git/blob - openlayers/tests/Format/XML.html
add some margin around image
[syp.git] / openlayers / tests / Format / XML.html
1 <html> 
2 <head> 
3     <script src="../../lib/OpenLayers.js"></script> 
4     <script type="text/javascript">
5
6     var text =
7         '<?xml version="1.0"?>' + 
8         '<ol:root xmlns="http://namespace.default.net" ' +
9                  'xmlns:ol="http://namespace.openlayers.org" ' + 
10                  'xmlns:ta="http://namespace.testattribute.net">' +
11             '<ol:child ta:attribute="value1" ' +
12                       'attribute="value2">' +
13                 'junk1' +
14             '<' + '/ol:child>' +
15             '<ol:child>junk2<' + '/ol:child>' +
16             '<ol:child>junk3<' + '/ol:child>' +
17             '<element>junk4<' + '/element>' + 
18             '<ol:element>junk5<' + '/ol:element>' + 
19             '<ol:p>' +
20                 '<ol:a>junk' +
21                 '<' + '/ol:a>' + 
22                 '<ol:b>junk' +
23                 '<' + '/ol:b>' + 
24                 '<ol:a>junk' +
25                 '<' + '/ol:a>' + 
26             '<' + '/ol:p>' + 
27         '<' + '/ol:root>';
28
29     function test_Format_XML_constructor(t) { 
30         t.plan(13); 
31          
32         var options = {'foo': 'bar'}; 
33         var format = new OpenLayers.Format.XML(options); 
34         t.ok(format instanceof OpenLayers.Format.XML, 
35              "new OpenLayers.Format.XML returns object" ); 
36         t.eq(format.foo, "bar", "constructor sets options correctly"); 
37         t.eq(typeof format.read, "function", "format has a read function"); 
38         t.eq(typeof format.write, "function", "format has a write function");
39
40         t.ok(!window.ActiveXObject || format.xmldom, "browsers with activeX must have xmldom");
41         
42         // test namespaces
43         t.ok(format.namespaces instanceof Object, "format has namespace object");
44         var namespaces = {"foo": "bar"};
45         format = new OpenLayers.Format.XML({namespaces: namespaces});
46         t.eq(format.namespaces, namespaces, "format.namespaces correctly set in constructor");
47         
48         // test default prefix
49         t.eq(format.defaultPrefix, null, "defaultPrefix is null by default");
50         format = new OpenLayers.Format.XML({defaultPrefix: "foo"});
51         t.eq(format.defaultPrefix, "foo", "defaultPrefix correctly set in constructor");
52
53         // test readers
54         t.ok(format.readers instanceof Object, "format has readers object");
55         var readers = {"foo": "bar"};
56         format = new OpenLayers.Format.XML({readers: readers});
57         t.eq(format.readers, readers, "format.readers correctly set in constructor");
58
59         // test readers
60         t.ok(format.writers instanceof Object, "format has writers object");
61         var writers = {"foo": "bar"};
62         format = new OpenLayers.Format.XML({writers: writers});
63         t.eq(format.writers, writers, "format.writers correctly set in constructor");
64     }
65     
66     function test_destroy(t) {
67         t.plan(1);
68         var format = new OpenLayers.Format.XML();
69         format.destroy();
70         t.eq(format.xmldom, null, "xmldom set to null for all browsers");
71     }
72
73     function test_Format_XML_read(t) {
74         
75         var format = new OpenLayers.Format.XML();
76         t.plan(format.xmldom ? 10 : 9);
77
78         var doc = format.read(text);
79         t.eq(doc.nodeType, 9,
80              "doc has the correct node type");
81         t.eq(doc.nodeName, "#document",
82              "doc has the correct node name");
83         t.ok(doc.documentElement,
84              "ok to access doc.documentElement");
85         t.xml_eq(doc.documentElement, text,
86                  "doc.documentElement correctly read");
87         
88         // read can also be called on the prototype directly
89         doc = OpenLayers.Format.XML.prototype.read(text);
90         t.eq(doc.nodeType, 9,
91              "doc has the correct node type");
92         t.eq(doc.nodeName, "#document",
93              "doc has the correct node name");
94         t.ok(doc.documentElement,
95              "ok to access doc.documentElement");
96         t.xml_eq(doc.documentElement, text,
97                  "doc.documentElement correctly read");
98         
99         // where appropriate, make sure doc is loaded into xmldom property
100         if(format.xmldom) {
101             t.xml_eq(format.xmldom.documentElement, text,
102                      "xmldom.documentElement contains equivalent xml");
103         }
104         
105         // test equivalence with different namespace alias
106         var pre1 = 
107             "<pre1:parent xmlns:pre1='http://namespace'>" +
108                 "<pre1:child1>value2</pre1:child1>" +
109                 "<pre1:child2 pre1:attr1='foo'>value2</pre1:child2>" +
110                 "<pre1:child3 chicken:attr='hot' xmlns:chicken='http://soup'/>" +
111             "</pre1:parent>";
112         var pre2 = 
113             "<pre2:parent xmlns:pre2='http://namespace'>" +
114                 "<pre2:child1>value2</pre2:child1>" +
115                 "<pre2:child2 pre2:attr1='foo'>value2</pre2:child2>" +
116                 "<pre2:child3 pea:attr='hot' xmlns:pea='http://soup'/>" +
117             "</pre2:parent>";
118         var doc1 = format.read(pre1);
119         t.xml_eq(doc1.documentElement, pre2, "read correctly sets namespaces");
120         
121     }
122
123     function test_Format_XML_write(t) {
124         t.plan(2);
125
126         var format = new OpenLayers.Format.XML();
127         var doc = format.read(text);
128         var out = format.write(doc);
129         out = out.replace(/[\r\n]/g, '');
130         out = out.replace( /<\?.*\?>/, '')
131         var expected = text.replace(/<\?.*\?>/, '')
132         t.eq(expected, out,
133              "correctly writes an XML DOM doc");
134         var out = format.write(
135           format.getElementsByTagNameNS(doc,
136            "http://namespace.openlayers.org","root")[0]);
137         out = out.replace(/[\r\n]/g, '');
138         out = out.replace( /<\?.*\?>/, '')
139         t.eq(out, expected,
140              "correctly writes an XML DOM node");
141     }
142
143     function test_Format_XML_createElementNS(t) {
144         t.plan(5);
145
146         var format = new OpenLayers.Format.XML();
147         var uri = "http://foo.com";
148         var prefix = "foo";
149         var localName = "bar";
150         var qualifiedName = prefix + ":" + name;
151         var node = format.createElementNS(uri, qualifiedName);
152         t.eq(node.nodeType, 1,
153              "node has correct type");
154         t.eq(node.nodeName, qualifiedName,
155              "node has correct qualified name");
156         t.eq(node.prefix, prefix,
157              "node has correct prefix");
158         t.eq(node.namespaceURI, uri,
159              "node has correct namespace uri");
160         
161         var doc = format.read(text);
162         if (doc.importNode) {
163             node = doc.importNode(node, true);
164         }    
165         t.ok(doc.documentElement.appendChild(node),
166              "node can be appended to a doc root");
167     }
168
169     function test_Format_XML_createTextNode(t) {
170         t.plan(4);
171
172         var format = new OpenLayers.Format.XML();
173         var value = Math.random().toString();
174         var node = format.createTextNode(value);
175         t.eq(node.nodeType, 3,
176              "node has correct type");
177         t.eq(node.nodeName, "#text",
178              "node has correct name");
179         t.eq(node.nodeValue, value,
180              "node has correct value");
181         
182         var doc = format.read(text);
183         if (doc.importNode) {
184             node = doc.importNode(node, true);
185         }    
186         t.ok(doc.documentElement.appendChild(node),
187              "node can be appended to a doc root");
188     }
189
190     function test_Format_XML_getElementsByTagNameNS(t) {
191         t.plan(5);
192
193         var format = new OpenLayers.Format.XML();
194         var olUri = "http://namespace.openlayers.org";
195         var name = "child";
196         var doc = format.read(text);
197         var nodes = format.getElementsByTagNameNS(doc.documentElement,
198                                                   olUri, name);
199         t.eq(nodes.length, 3,
200              "gets correct number of nodes");
201         var qualifiedName = nodes[0].prefix + ":" + name;
202         t.eq(nodes[0].nodeName, qualifiedName,
203              "first node has correct qualified name");
204         
205         var defaultUri = "http://namespace.default.net";
206         name = "element";
207         nodes = format.getElementsByTagNameNS(doc.documentElement,
208                                                   defaultUri, name);
209         t.eq(nodes.length, 1,
210              "gets correct number of nodes in default namespace");
211         
212         var pList = format.getElementsByTagNameNS(doc.documentElement,
213                                                   olUri, "p");
214         t.eq(pList.length, 1, "got one ol:p element");
215         var p = pList[0];
216         
217         var aList = format.getElementsByTagNameNS(p, olUri, "a");
218         t.eq(aList.length, 2, "got two child ol:a elements");
219         
220         
221         
222     }
223
224     function test_Format_XML_getAttributeNodeNS(t) {
225         t.plan(5);
226
227         var format = new OpenLayers.Format.XML();
228         var doc = format.read(text);
229         var olUri = "http://namespace.openlayers.org";
230         var taUri = "http://namespace.testattribute.net";
231         var localNodeName = "child";
232         var localAttrName = "attribute";
233         var nodes = format.getElementsByTagNameNS(doc.documentElement,
234                                                   olUri, localNodeName);
235         var attributeNode = format.getAttributeNodeNS(nodes[0],
236                                                       taUri, localAttrName);
237         var qualifiedName = attributeNode.prefix + ":" + localAttrName;
238
239         t.ok(attributeNode,
240              "returns non-null value");
241         t.eq(attributeNode.nodeType, 2,
242              "attribute node has correct type");
243         t.eq(attributeNode.nodeName, qualifiedName,
244              "attribute node has correct qualified name");
245         t.eq(attributeNode.nodeValue, "value1",
246              "attribute node has correct value");
247         
248         var nullAttribute = format.getAttributeNodeNS(nodes[0],
249                                                       taUri, "nothing");
250         t.ok(nullAttribute === null,
251              "returns null for nonexistent attribute");
252     }
253
254     function test_Format_XML_getAttributeNS(t) {
255         t.plan(2);
256
257         var format = new OpenLayers.Format.XML();
258         var doc = format.read(text);
259         var olUri = "http://namespace.openlayers.org";
260         var taUri = "http://namespace.testattribute.net";
261         var localNodeName = "child";
262         var localAttrName = "attribute";
263         var nodes = format.getElementsByTagNameNS(doc.documentElement,
264                                                   olUri, localNodeName);
265         var attributeValue = format.getAttributeNS(nodes[0],
266                                                    taUri, localAttrName);
267         t.eq(attributeValue, "value1",
268              "got correct attribute value");
269         
270         var emptyValue = format.getAttributeNS(nodes[0],
271                                               taUri, "nothing");
272         t.ok(emptyValue === "",
273              "returns empty string for nonexistent attributes");
274     }
275
276     function test_Format_XML_hasAttributeNS(t) {
277         t.plan(2);
278
279         var format = new OpenLayers.Format.XML();
280         var doc = format.read(text);
281         var olUri = "http://namespace.openlayers.org";
282         var taUri = "http://namespace.testattribute.net";
283         var localNodeName = "child";
284         var localAttrName = "attribute";
285         var nodes = format.getElementsByTagNameNS(doc.documentElement,
286                                                   olUri, localNodeName);
287         var found = format.hasAttributeNS(nodes[0], taUri, localAttrName);
288         t.ok(found === true, "returns true for good attribute");
289         
290         found = format.hasAttributeNS(nodes[0], taUri, "nothing");
291         t.ok(found === false, "returns false for bad attribute");
292     }
293     
294     function test_namespaces(t) {
295         t.plan(2);
296         
297         var format = new OpenLayers.Format.XML({
298             namespaces: {
299                 "def": "http://example.com/default",
300                 "foo": "http://example.com/foo",
301                 "bar": "http://example.com/bar"
302             },
303             defaultPrefix: "def"
304         });
305         
306         // test that prototype has not been altered
307         t.eq(OpenLayers.Format.XML.prototype.namespaces, null,
308              "setting namespaces at construction does not modify prototype");
309         
310         // test that namespaceAlias has been set
311         t.eq(format.namespaceAlias["http://example.com/foo"], "foo",
312              "namespaceAlias mapping has been set");
313         
314     }
315     
316     function test_setNamespace(t) {
317         t.plan(3);
318         
319         var format = new OpenLayers.Format.XML();
320         
321         // test that namespaces is an object
322         t.ok(format.namespaces instanceof Object, "empty namespace object set");
323         
324         format.setNamespace("foo", "http://example.com/foo");
325         t.eq(format.namespaces["foo"], "http://example.com/foo", "alias -> uri mapping set");
326         t.eq(format.namespaceAlias["http://example.com/foo"], "foo", "uri -> alias mapping set");
327
328     }
329     
330     function test_readChildNodes(t) {
331         
332         var text = "<?xml version='1.0' encoding='UTF-8'?>" +
333         "<container xmlns='http://example.com/foo'>" +
334             "<marker name='my marker 1'>" +
335                 "<position>" +
336                     "<lon>-180</lon>" +
337                     "<lat>90</lat>" +
338                 "</position>" +
339                 "<detail>some text for first marker</detail>" +
340                 "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>" +
341             "</marker>" +
342             "<marker name='my marker 2'>" +
343                 "<position>" +
344                     "<lon>180</lon>" +
345                     "<lat>-90</lat>" +
346                 "</position>" +
347                 "<detail>some text for second marker</detail>" +
348                 "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>" +
349             "</marker>" +
350         "</container>";
351         
352         var expect = [
353             new OpenLayers.Feature.Vector(
354                 new OpenLayers.Geometry.Point(-180, 90),
355                 {
356                     name: 'my marker 1',
357                     link: 'http://host/path/1',
358                     detail: 'some text for first marker'
359                 }
360             ),
361             new OpenLayers.Feature.Vector(
362                 new OpenLayers.Geometry.Point(180, -90),
363                 {
364                     name: 'my marker 2',
365                     link: 'http://host/path/2',
366                     detail: 'some text for second marker'
367                 }
368             )
369         ];
370         
371         var format = new OpenLayers.Format.XML({
372             defaultPrefix: "foo",
373             namespaces: {
374                 "foo": "http://example.com/foo",
375                 "atom": "http://www.w3.org/2005/Atom"
376             },
377             readers: {
378                 "foo": {
379                     "container": function(node, obj) {
380                         var list = [];
381                         this.readChildNodes(node, list);
382                         obj.list = list;
383                     },
384                     "marker": function(node, list) {
385                         var feature = new OpenLayers.Feature.Vector();
386                         feature.attributes.name = node.getAttribute("name");
387                         this.readChildNodes(node, feature);
388                         list.push(feature);
389                     },
390                     "position": function(node, feature) {
391                         var obj = {};
392                         this.readChildNodes(node, obj);
393                         feature.geometry = new OpenLayers.Geometry.Point(obj.x, obj.y);
394                     },
395                     "lon": function(node, obj) {
396                         obj.x = this.getChildValue(node);
397                     },
398                     "lat": function(node, obj) {
399                         obj.y = this.getChildValue(node);
400                     },
401                     "detail": function(node, feature) {
402                         feature.attributes.detail = this.getChildValue(node);
403                     }
404                 },
405                 "atom": {
406                     "link": function(node, feature) {
407                         feature.attributes.link = node.getAttribute("href");
408                     }                    
409                 }
410             }
411         });
412         
413         // convert text to document node
414         var doc = format.read(text);
415         // read child nodes to get back some object
416         var obj = format.readChildNodes(doc);
417         // start comparing what we got to what we expect
418         var got = obj.list;
419         
420         t.plan(11);
421         t.eq(got.length, expect.length, "correct number of items parsed");
422         t.eq(got[0].geometry.x, expect[0].geometry.x, "correct x coord parsed for marker 1");
423         t.eq(got[0].geometry.y, expect[0].geometry.y, "correct y coord parsed for marker 1");
424         t.eq(got[0].attributes.name, expect[0].attributes.name, "correct name parsed for marker 1");
425         t.eq(got[0].attributes.detail, expect[0].attributes.detail, "correct detail parsed for marker 1");
426         t.eq(got[0].attributes.link, expect[0].attributes.link, "correct link parsed for marker 1");
427         t.eq(got[1].geometry.x, expect[1].geometry.x, "correct x coord parsed for marker 2");
428         t.eq(got[1].geometry.y, expect[1].geometry.y, "correct y coord parsed for marker 2");
429         t.eq(got[1].attributes.name, expect[1].attributes.name, "correct name parsed for marker 2");
430         t.eq(got[1].attributes.detail, expect[1].attributes.detail, "correct detail parsed for marker 2");
431         t.eq(got[1].attributes.link, expect[1].attributes.link, "correct link parsed for marker 2");
432         
433     }
434     
435     function test_writeNode(t) {
436         
437         var features = [
438             new OpenLayers.Feature.Vector(
439                 new OpenLayers.Geometry.Point(-180, 90),
440                 {
441                     name: 'my marker 1',
442                     link: 'http://host/path/1',
443                     detail: 'some text for first marker'
444                 }
445             ),
446             new OpenLayers.Feature.Vector(
447                 new OpenLayers.Geometry.Point(180, -90),
448                 {
449                     name: 'my marker 2',
450                     link: 'http://host/path/2',
451                     detail: 'some text for second marker'
452                 }
453             )
454         ];
455
456         var expect = "<?xml version='1.0' encoding='UTF-8'?>" +
457         "<container xmlns='http://example.com/foo'>" +
458             "<marker name='my marker 1'>" +
459                 "<position>" +
460                     "<lon>-180</lon>" +
461                     "<lat>90</lat>" +
462                 "</position>" +
463                 "<detail>some text for first marker</detail>" +
464                 "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>" +
465             "</marker>" +
466             "<marker name='my marker 2'>" +
467                 "<position>" +
468                     "<lon>180</lon>" +
469                     "<lat>-90</lat>" +
470                 "</position>" +
471                 "<detail>some text for second marker</detail>" +
472                 "<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>" +
473             "</marker>" +
474         "</container>";
475         
476         var format = new OpenLayers.Format.XML({
477             defaultPrefix: "foo",
478             namespaces: {
479                 "foo": "http://example.com/foo",
480                 "atom": "http://www.w3.org/2005/Atom"
481             },
482             writers: {
483                 "foo": {
484                     "container": function(features) {
485                         var node = this.createElementNSPlus("container");
486                         var feature;
487                         for(var i=0; i<features.length; ++i) {
488                             feature = features[i];
489                             this.writeNode("marker", features[i], node);
490                         }
491                         return node;
492                     },
493                     "marker": function(feature) {
494                         var node = this.createElementNSPlus("marker", {
495                             attributes: {name: feature.attributes.name}
496                         });
497                         this.writeNode("position", feature.geometry, node);
498                         this.writeNode("detail", feature.attributes.detail, node);
499                         this.writeNode("atom:link", feature.attributes.link, node);
500                         return node;
501                     },
502                     "position": function(geometry) {
503                         var node = this.createElementNSPlus("position");
504                         this.writeNode("lon", geometry.x, node);
505                         this.writeNode("lat", geometry.y, node);
506                         return node;
507                     },
508                     "lon": function(x) {
509                         return this.createElementNSPlus("lon", {
510                             value: x
511                         });
512                     },
513                     "lat": function(y) {
514                         return this.createElementNSPlus("lat", {
515                             value: y
516                         });
517                     },
518                     "detail": function(text) {
519                         return this.createElementNSPlus("detail", {
520                             value: text
521                         });
522                     }
523                 },
524                 "atom": {
525                     "link": function(href) {
526                         return this.createElementNSPlus("atom:link", {
527                             attributes: {href: href}
528                         });
529                     }
530                 }
531             }
532             
533         });
534         
535         t.plan(1);
536         // test that we get what we expect from writeNode
537         var got = format.writeNode("container", features);
538         t.xml_eq(got, expect, "features correctly written");
539     }
540     
541     function test_createElementNSPlus(t) {
542         
543         var format = new OpenLayers.Format.XML({
544             defaultPrefix: "def",
545             namespaces: {
546                 "def": "http://example.com/default",
547                 "foo": "http://example.com/foo",
548                 "bar": "http://example.com/bar"
549             }
550         });
551         
552         var cases = [
553             {
554                 description: "unprefixed name with default options",
555                 node: format.createElementNSPlus("FooNode"),
556                 expect: "<def:FooNode xmlns:def='http://example.com/default'/>"
557             }, {
558                 description: "def prefixed name with default options",
559                 node: format.createElementNSPlus("def:FooNode"),
560                 expect: "<def:FooNode xmlns:def='http://example.com/default'/>"
561             }, {
562                 description: "foo prefixed name with default options",
563                 node: format.createElementNSPlus("foo:FooNode"),
564                 expect: "<foo:FooNode xmlns:foo='http://example.com/foo'/>"
565             }, {
566                 description: "unprefixed name with uri option",
567                 node: format.createElementNSPlus("FooNode", {
568                     uri: "http://example.com/elsewhere"
569                 }),
570                 expect: "<FooNode xmlns='http://example.com/elsewhere'/>"
571             }, {
572                 description: "foo prefixed name with uri option (overriding format.namespaces)",
573                 node: format.createElementNSPlus("foo:FooNode", {
574                     uri: "http://example.com/elsewhere"
575                 }),
576                 expect: "<foo:FooNode xmlns:foo='http://example.com/elsewhere'/>"
577             }, {
578                 description: "foo prefixed name with attributes option",
579                 node: format.createElementNSPlus("foo:FooNode", {
580                     attributes: {
581                         "id": "123",
582                         "foo:attr1": "namespaced attribute 1",
583                         "bar:attr2": "namespaced attribute 2"
584                     }
585                 }),
586                 expect: "<foo:FooNode xmlns:foo='http://example.com/foo' xmlns:bar='http://example.com/bar' id='123' foo:attr1='namespaced attribute 1' bar:attr2='namespaced attribute 2'/>"
587             }, {
588                 description: "foo prefixed name with attributes and value options",
589                 node: format.createElementNSPlus("foo:FooNode", {
590                     attributes: {"id": "123"},
591                     value: "text value"
592                 }),
593                 expect: "<foo:FooNode xmlns:foo='http://example.com/foo' id='123'>text value<" + "/foo:FooNode>"
594             }, {
595                 description: "value of 0 gets appended as a text node",
596                 node: format.createElementNSPlus("foo:bar", {value: 0}),
597                 expect: "<foo:bar xmlns:foo='http://example.com/foo'>0</foo:bar>"
598             }, {
599                 description: "value of true gets appended as a text node",
600                 node: format.createElementNSPlus("foo:bar", {value: true}),
601                 expect: "<foo:bar xmlns:foo='http://example.com/foo'>true</foo:bar>"
602             }, {
603                 description: "value of false gets appended as a text node",
604                 node: format.createElementNSPlus("foo:bar", {value: false}),
605                 expect: "<foo:bar xmlns:foo='http://example.com/foo'>false</foo:bar>"
606             }, {
607                 description: "null value does not get appended as a text node",
608                 node: format.createElementNSPlus("foo:bar", {value: null}),
609                 expect: "<foo:bar xmlns:foo='http://example.com/foo'/>"
610             }, {
611                 description: "undefined value does not get appended as a text node",
612                 node: format.createElementNSPlus("foo:bar"),
613                 expect: "<foo:bar xmlns:foo='http://example.com/foo'/>"
614             }
615         ];
616         
617         t.plan(cases.length);
618         var test;
619         for(var i=0; i<cases.length; ++i) {
620             test = cases[i];
621             t.xml_eq(test.node, test.expect, test.description);
622         }
623         
624     }
625     
626     function test_setAttributes(t) {
627         
628         var format = new OpenLayers.Format.XML({
629             defaultPrefix: "def",
630             namespaces: {
631                 "def": "http://example.com/default",
632                 "foo": "http://example.com/foo",
633                 "bar": "http://example.com/bar"
634             }
635         });
636         
637         var cases = [
638             {
639                 description: "unprefixed attribute",
640                 node: format.createElementNSPlus("foo:Node"),
641                 attributes: {"id": "123"},
642                 expect: "<foo:Node xmlns:foo='http://example.com/foo' id='123'/>"
643             }, {
644                 description: "foo prefixed attribute",
645                 node: format.createElementNSPlus("foo:Node"),
646                 attributes: {"foo:id": "123"},
647                 expect: "<foo:Node xmlns:foo='http://example.com/foo' foo:id='123'/>"
648             }, {
649                 description: "foo prefixed attribute with def prefixed node",
650                 node: format.createElementNSPlus("def:Node"),
651                 attributes: {"foo:id": "123"},
652                 expect: "<def:Node xmlns:def='http://example.com/default' xmlns:foo='http://example.com/foo' foo:id='123'/>"
653             }, {
654                 description: "multiple attributes",
655                 node: format.createElementNSPlus("def:Node"),
656                 attributes: {"id": "123", "foo": "bar"},
657                 expect: "<def:Node xmlns:def='http://example.com/default' id='123' foo='bar'/>"
658             }
659         ];
660         
661         t.plan(cases.length);
662         var test;
663         for(var i=0; i<cases.length; ++i) {
664             test = cases[i];
665             format.setAttributes(test.node, test.attributes);
666             t.xml_eq(test.node, test.expect, test.description);
667         }
668         
669     }
670
671     function test_keepData(t) { 
672         t.plan(2);
673
674         var options = {'keepData': true};
675         var format = new OpenLayers.Format.XML(options); 
676         format.read(text);
677
678         t.ok(format.data != null, 'data property is not null after read with keepData=true');
679         t.eq(format.data.documentElement.tagName,'ol:root','keepData keeps the right data');
680     }
681
682     function test_getChildValue(t) {
683
684         t.plan(1);
685
686         var text =
687             "<?xml version='1.0' encoding='UTF-8'?>" +
688             "<root>" +
689                 "x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;" +
690             "</root>";
691
692         var format = new OpenLayers.Format.XML();
693         var doc = format.read(text).documentElement;
694
695         t.eq(format.getChildValue(doc), "xyzzy", "child value skips comments, concatenates multiple values, reads through entities");
696
697     }
698     
699     function test_getChildEl(t) {
700
701         t.plan(3);
702
703         var text =
704             "<?xml version='1.0' encoding='UTF-8'?>" +
705             "<root>" +
706                 "<!-- comment -->" +
707                 "<a>x</a>" +
708                 "<b>x</b>" +
709             "</root>";
710
711         var format = new OpenLayers.Format.XML();
712         var doc = format.read(text).documentElement;
713
714         var a = format.getChildEl(doc);
715         t.eq(a.nodeName, "a", "first element found correctly");
716         
717         a = format.getChildEl(doc, "a");
718         t.eq(b, null, "first child element matches the given name");
719
720         var b = format.getChildEl(doc, "b");
721         t.eq(b, null, "first child element does not match the given name");
722
723     }
724     
725     function test_getNextEl(t) {
726         t.plan(5);
727
728         var text =
729             "<?xml version='1.0' encoding='UTF-8'?>" +
730             "<root>" +
731                 "<!-- comment -->" +
732                 "<a>x</a>" +
733                 "<!-- comment -->" +
734                 "<b xmlns='urn:example'>x</b>" +
735             "</root>";
736
737         var format = new OpenLayers.Format.XML();
738         var doc = format.read(text).documentElement;
739
740         var a = format.getChildEl(doc);
741         
742         var b = format.getNextEl(a);
743         t.eq(b && b.nodeName, "b", "next element correctly found");
744         
745         b = format.getNextEl(a, "b");
746         t.eq(b && b.nodeName, "b", "next element correctly found when name supplied");
747
748         b = format.getNextEl(a, "c");
749         t.eq(b, null, "null returned when name does not match next element");
750
751         b = format.getNextEl(a, null, "urn:example");
752         t.eq(b && b.nodeName, "b", "next element correctly found when namespace supplied");
753
754         b = format.getNextEl(a, null, "foo");
755         t.eq(b, null, "null returned when namespace does not match next element");
756
757     }
758     
759     function test_isSimpleContent(t) {
760         t.plan(2);
761
762         var text =
763             "<?xml version='1.0' encoding='UTF-8'?>" +
764             "<root>" +
765                 "<!-- comment -->" +
766                 "<a>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;</a>" +
767                 "<!-- comment -->" +
768                 "<b>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z&#x79;</b>" +
769             "</root>";
770
771         var format = new OpenLayers.Format.XML();
772         var doc = format.read(text).documentElement;
773
774         var a = format.getChildEl(doc);
775         var b = format.getNextEl(a);
776         t.ok(!format.isSimpleContent(a), "<a> content is not simple");
777         t.ok(format.isSimpleContent(b), "<b> content is simple");
778
779     }
780
781     function test_lookupNamespaceURI(t) {
782         
783         t.plan(8);
784
785         var text =
786             "<?xml version='1.0' encoding='UTF-8'?>" +
787             "<root xmlns:baz='urn:baznamespace'>" +
788                 "<!-- comment -->" +
789                 "<a><foo /></a>" +
790                 "<!-- comment -->" +
791                 "<b xmlns='urn:example'><!-- comment --><bar foo='value'/></b>" +
792             "</root>";
793
794         var format = new OpenLayers.Format.XML();
795         var doc = format.read(text).documentElement;
796
797         var a = format.getChildEl(doc);
798         t.eq(format.lookupNamespaceURI(a, "baz"), "urn:baznamespace", "prefix lookup on first child");
799
800         var foo = format.getChildEl(a);
801         t.eq(format.lookupNamespaceURI(foo, "baz"), "urn:baznamespace", "prefix lookup on child of first child");
802         
803         var b = format.getNextEl(a);
804         t.eq(format.lookupNamespaceURI(b, null), "urn:example", "default namespace lookup on element");
805         
806         var bar = format.getChildEl(b);
807         t.eq(format.lookupNamespaceURI(bar, null), "urn:example", "default namespace lookup on child");
808         t.eq(format.lookupNamespaceURI(bar, "baz"), "urn:baznamespace", "prefix lookup on child with different default");
809
810         // test that the alias behaves properly
811         var lookup = OpenLayers.Format.XML.lookupNamespaceURI;
812         t.eq(lookup(bar, "baz"), "urn:baznamespace", "(alias) prefix lookup on child with different default");
813
814         var attr = bar.attributes[0];
815         // Internet Explorer didn't have the ownerElement property until 8.
816         var supportsOwnerElement = !!attr.ownerElement;        
817         if(supportsOwnerElement) {
818             t.eq(format.lookupNamespaceURI(attr, null), "urn:example", "default namespace lookup on attribute");
819             t.eq(format.lookupNamespaceURI(attr, "baz"), "urn:baznamespace", "prefix lookup on attribute with different default");
820         } else {
821             t.debug_print("namespace lookup on attributes not supported in this browser");
822             t.ok(true, "namespace lookup on attributes not supported in this browser");
823             t.ok(true, "namespace lookup on attributes not supported in this browser");
824         }
825
826     }
827     
828
829     
830     </script> 
831 </head> 
832 <body> 
833 </body> 
834 </html>