merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mcs / class / System.XML / Test / System.Xml.XPath / XPathNavigatorTests.cs
1 //
2 // MonoTests.System.Xml.XPathNavigatorTests
3 //
4 // Authors:
5 //   Jason Diamond <jason@injektilo.org>
6 //   Martin Willemoes Hansen <mwh@sysrq.dk>
7 //   Atsushi Enomoto <atsushi@ximian.com>
8 //
9 // (C) 2002 Jason Diamond
10 // (C) 2003 Martin Willemoes Hansen
11 // (C) 2004-2006 Novell, Inc.
12 //
13
14 using System;
15 using System.IO;
16 using System.Xml;
17 using System.Xml.XPath;
18 using System.Xml.Xsl;
19
20 using NUnit.Framework;
21
22 namespace MonoTests.System.Xml
23 {
24         [TestFixture]
25         public class XPathNavigatorTests : Assertion
26         {
27                 XmlDocument document;
28                 XPathNavigator navigator;
29
30                 [SetUp]
31                 public void GetReady ()
32                 {
33                         document = new XmlDocument ();
34                 }
35                 
36                 [Test]
37                 public void CreateNavigator ()
38                 {
39                         document.LoadXml ("<foo />");
40                         navigator = document.CreateNavigator ();
41                         AssertNotNull (navigator);
42                 }
43
44                 [Test]
45                 public void PropertiesOnDocument ()
46                 {
47                         document.LoadXml ("<foo:bar xmlns:foo='#foo' />");
48                         navigator = document.CreateNavigator ();
49                         
50                         AssertEquals (XPathNodeType.Root, navigator.NodeType);
51                         AssertEquals (String.Empty, navigator.Name);
52                         AssertEquals (String.Empty, navigator.LocalName);
53                         AssertEquals (String.Empty, navigator.NamespaceURI);
54                         AssertEquals (String.Empty, navigator.Prefix);
55                         Assert (!navigator.HasAttributes);
56                         Assert (navigator.HasChildren);
57                         Assert (!navigator.IsEmptyElement);
58                 }
59
60                 [Test]
61                 public void PropertiesOnElement ()
62                 {
63                         document.LoadXml ("<foo:bar xmlns:foo='#foo' />");
64                         navigator = document.DocumentElement.CreateNavigator ();
65                         
66                         AssertEquals (XPathNodeType.Element, navigator.NodeType);
67                         AssertEquals ("foo:bar", navigator.Name);
68                         AssertEquals ("bar", navigator.LocalName);
69                         AssertEquals ("#foo", navigator.NamespaceURI);
70                         AssertEquals ("foo", navigator.Prefix);
71                         Assert (!navigator.HasAttributes);
72                         Assert (!navigator.HasChildren);
73                         Assert (navigator.IsEmptyElement);
74                 }
75
76                 [Test]
77                 public void PropertiesOnAttribute ()
78                 {
79                         document.LoadXml ("<foo bar:baz='quux' xmlns:bar='#bar' />");
80                         navigator = document.DocumentElement.GetAttributeNode("baz", "#bar").CreateNavigator ();
81                         
82                         AssertEquals (XPathNodeType.Attribute, navigator.NodeType);
83                         AssertEquals ("bar:baz", navigator.Name);
84                         AssertEquals ("baz", navigator.LocalName);
85                         AssertEquals ("#bar", navigator.NamespaceURI);
86                         AssertEquals ("bar", navigator.Prefix);
87                         Assert (!navigator.HasAttributes);
88                         Assert (!navigator.HasChildren);
89                         Assert (!navigator.IsEmptyElement);
90                 }
91
92                 [Test]
93                 public void PropertiesOnNamespace ()
94                 {
95                         document.LoadXml ("<root xmlns='urn:foo' />");\r
96                         navigator = document.DocumentElement.Attributes [0].CreateNavigator ();\r
97                         AssertEquals (XPathNodeType.Namespace, navigator.NodeType);
98                 }
99
100                 [Test]
101                 public void Navigation ()
102                 {
103                         document.LoadXml ("<foo><bar /><baz /></foo>");
104                         navigator = document.DocumentElement.CreateNavigator ();
105                         
106                         AssertEquals ("foo", navigator.Name);
107                         Assert (navigator.MoveToFirstChild ());
108                         AssertEquals ("bar", navigator.Name);
109                         Assert (navigator.MoveToNext ());
110                         AssertEquals ("baz", navigator.Name);
111                         Assert (!navigator.MoveToNext ());
112                         AssertEquals ("baz", navigator.Name);
113                         Assert (navigator.MoveToPrevious ());
114                         AssertEquals ("bar", navigator.Name);
115                         Assert (!navigator.MoveToPrevious ());
116                         Assert (navigator.MoveToParent ());
117                         AssertEquals ("foo", navigator.Name);
118                         navigator.MoveToRoot ();
119                         AssertEquals (XPathNodeType.Root, navigator.NodeType);
120                         Assert (!navigator.MoveToParent ());
121                         AssertEquals (XPathNodeType.Root, navigator.NodeType);
122                         Assert (navigator.MoveToFirstChild ());
123                         AssertEquals ("foo", navigator.Name);
124                         Assert (navigator.MoveToFirst ());
125                         AssertEquals ("foo", navigator.Name);
126                         Assert (navigator.MoveToFirstChild ());
127                         AssertEquals ("bar", navigator.Name);
128                         Assert (navigator.MoveToNext ());
129                         AssertEquals ("baz", navigator.Name);
130                         Assert (navigator.MoveToFirst ());
131                         AssertEquals ("bar", navigator.Name);
132                 }
133
134                 [Test]
135                 public void MoveToAndIsSamePosition ()
136                 {
137                         XmlDocument document1 = new XmlDocument ();
138                         document1.LoadXml ("<foo><bar /></foo>");
139                         XPathNavigator navigator1a = document1.DocumentElement.CreateNavigator ();
140                         XPathNavigator navigator1b = document1.DocumentElement.CreateNavigator ();
141
142                         XmlDocument document2 = new XmlDocument ();
143                         document2.LoadXml ("<foo><bar /></foo>");
144                         XPathNavigator navigator2 = document2.DocumentElement.CreateNavigator ();
145
146                         AssertEquals ("foo", navigator1a.Name);
147                         Assert (navigator1a.MoveToFirstChild ());
148                         AssertEquals ("bar", navigator1a.Name);
149
150                         Assert (!navigator1b.IsSamePosition (navigator1a));
151                         AssertEquals ("foo", navigator1b.Name);
152                         Assert (navigator1b.MoveTo (navigator1a));
153                         Assert (navigator1b.IsSamePosition (navigator1a));
154                         AssertEquals ("bar", navigator1b.Name);
155
156                         Assert (!navigator2.IsSamePosition (navigator1a));
157                         AssertEquals ("foo", navigator2.Name);
158                         Assert (!navigator2.MoveTo (navigator1a));
159                         AssertEquals ("foo", navigator2.Name);
160                 }
161
162                 [Test]
163                 public void AttributeNavigation ()
164                 {
165                         document.LoadXml ("<foo bar='baz' quux='quuux' />");
166                         navigator = document.DocumentElement.CreateNavigator ();
167
168                         AssertEquals (XPathNodeType.Element, navigator.NodeType);
169                         AssertEquals ("foo", navigator.Name);
170                         Assert (navigator.MoveToFirstAttribute ());
171                         AssertEquals (XPathNodeType.Attribute, navigator.NodeType);
172                         AssertEquals ("bar", navigator.Name);
173                         AssertEquals ("baz", navigator.Value);
174                         Assert (navigator.MoveToNextAttribute ());
175                         AssertEquals (XPathNodeType.Attribute, navigator.NodeType);
176                         AssertEquals ("quux", navigator.Name);
177                         AssertEquals ("quuux", navigator.Value);
178                 }
179
180                 [Test]
181                 public void ElementAndRootValues()
182                 {
183                         document.LoadXml ("<foo><bar>baz</bar><quux>quuux</quux></foo>");
184                         navigator = document.DocumentElement.CreateNavigator ();
185
186                         AssertEquals (XPathNodeType.Element, navigator.NodeType);
187                         AssertEquals ("foo", navigator.Name);
188                         //AssertEquals ("bazquuux", navigator.Value);
189
190                         navigator.MoveToRoot ();
191                         //AssertEquals ("bazquuux", navigator.Value);
192                 }
193
194                 [Test]
195                 public void DocumentWithXmlDeclaration ()
196                 {
197                         document.LoadXml ("<?xml version=\"1.0\" standalone=\"yes\"?><Root><foo>bar</foo></Root>");
198                         navigator = document.CreateNavigator ();
199
200                         navigator.MoveToRoot ();
201                         navigator.MoveToFirstChild ();
202                         AssertEquals (XPathNodeType.Element, navigator.NodeType);
203                         AssertEquals ("Root", navigator.Name);
204                 }
205
206                 [Test]
207                 public void DocumentWithProcessingInstruction ()
208                 {
209                         document.LoadXml ("<?xml-stylesheet href='foo.xsl' type='text/xsl' ?><foo />");
210                         navigator = document.CreateNavigator ();
211
212                         Assert (navigator.MoveToFirstChild ());
213                         AssertEquals (XPathNodeType.ProcessingInstruction, navigator.NodeType);
214                         AssertEquals ("xml-stylesheet", navigator.Name);
215
216                         XPathNodeIterator iter = navigator.SelectChildren (XPathNodeType.Element);
217                         AssertEquals (0, iter.Count);
218                 }
219
220                 [Test]
221                 public void SelectFromOrphan ()
222                 {
223                         // SelectSingleNode () from node without parent.
224                         XmlDocument doc = new XmlDocument ();
225                         doc.LoadXml ("<foo><include id='original' /></foo>");
226
227                         XmlNode node = doc.CreateElement ("child");
228                         node.InnerXml = "<include id='new' />";
229
230                         XmlNode new_include = node.SelectSingleNode ("//include");
231                         AssertEquals ("<include id=\"new\" />", new_include.OuterXml);
232
233                         // In this case 'node2' has parent 'node'
234                         doc = new XmlDocument ();
235                         doc.LoadXml ("<foo><include id='original' /></foo>");
236
237                         node = doc.CreateElement ("child");
238                         XmlNode node2 = doc.CreateElement ("grandchild");
239                         node.AppendChild (node2);
240                         node2.InnerXml = "<include id='new' />";
241
242                         new_include = node2.SelectSingleNode ("/");
243                         AssertEquals ("<child><grandchild><include id=\"new\" /></grandchild></child>",
244                                 new_include.OuterXml);
245                 }
246
247                 [Test]
248                 public void XPathDocumentMoveToId ()
249                 {
250                         string dtd = "<!DOCTYPE root [<!ELEMENT root EMPTY><!ATTLIST root id ID #REQUIRED>]>";\r
251                         string xml = dtd + "<root id='aaa'/>";\r
252                         StringReader sr = new StringReader (xml);\r
253                         XPathNavigator nav = new XPathDocument (sr).CreateNavigator ();\r
254                         Assert ("ctor() from TextReader", nav.MoveToId ("aaa"));\r
255
256                         XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null);\r
257                         nav = new XPathDocument (xvr).CreateNavigator ();\r
258                         Assert ("ctor() from XmlValidatingReader", nav.MoveToId ("aaa"));\r
259
260                         // FIXME: it seems to result in different in .NET 2.0.
261 #if NET_2_0
262 #else
263                         // When it is XmlTextReader, XPathDocument fails.
264                         XmlTextReader xtr = new XmlTextReader (xml, XmlNodeType.Document, null);\r
265                         nav = new XPathDocument (xtr).CreateNavigator ();\r
266                         Assert ("ctor() from XmlTextReader", !nav.MoveToId ("aaa"));\r
267                         xtr.Close ();\r
268 #endif
269                 }
270
271                 [Test]
272                 public void SignificantWhitespaceConstruction ()
273                 {
274                         string xml = @"<root>
275         <child xml:space='preserve'>    <!-- -->   </child>
276         <child xml:space='preserve'>    </child>
277 </root>";
278                         XPathNavigator nav = new XPathDocument (
279                                 new XmlTextReader (xml, XmlNodeType.Document, null),
280                                 XmlSpace.Preserve).CreateNavigator ();
281                         nav.MoveToFirstChild ();
282                         nav.MoveToFirstChild ();
283                         AssertEquals ("#1", XPathNodeType.Whitespace, nav.NodeType);
284                         nav.MoveToNext ();
285                         nav.MoveToFirstChild ();
286                         AssertEquals ("#2", XPathNodeType.SignificantWhitespace,
287                                 nav.NodeType);
288                 }
289
290                 [Test]
291                 public void VariableReference ()
292                 {
293                         XPathDocument xpd = new XPathDocument (
294                                 new StringReader ("<root>sample text</root>"));
295                         XPathNavigator nav = xpd.CreateNavigator ();
296
297                         XPathExpression expr = nav.Compile ("foo(string(.),$idx)");
298                         XsltArgumentList args = new XsltArgumentList ();
299                         args.AddParam ("idx", "", 5);
300                         MyContext ctx = new MyContext (nav.NameTable as NameTable, args);
301                         ctx.AddNamespace ("x", "urn:foo");
302
303                         expr.SetContext (ctx);
304
305                         XPathNodeIterator iter = nav.Select ("/root");
306                         iter.MoveNext ();
307                         AssertEquals ("e", iter.Current.Evaluate (expr));
308                 }
309
310                 class MyContext : XsltContext
311                 {
312                         XsltArgumentList args;
313
314                         public MyContext (NameTable nt, XsltArgumentList args)
315                                 : base (nt)
316                         {
317                                 this.args = args;
318                         }
319
320                         public override IXsltContextFunction ResolveFunction (
321                                 string prefix, string name, XPathResultType [] argtypes)
322                         {
323                                 if (name == "foo")
324                                         return new MyFunction (argtypes);
325                                 return null;
326                         }
327
328                         public override IXsltContextVariable ResolveVariable (string prefix, string name)
329                         {
330                                 return new MyVariable (name);
331                         }
332
333                         public override bool PreserveWhitespace (XPathNavigator nav)
334                         {
335                                 return false;
336                         }
337
338                         public override int CompareDocument (string uri1, string uri2)
339                         {
340                                 return String.CompareOrdinal (uri1, uri2);
341                         }
342
343                         public override bool Whitespace {
344                                 get { return false; }
345                         }
346
347                         public object GetParam (string name, string ns)
348                         {
349                                 return args.GetParam (name, ns);
350                         }
351                 }
352
353                 public class MyFunction : IXsltContextFunction
354                 {
355                         XPathResultType [] argtypes;
356
357                         public MyFunction (XPathResultType [] argtypes)
358                         {
359                                 this.argtypes = argtypes;
360                         }
361
362                         public XPathResultType [] ArgTypes {
363                                 get { return argtypes; }
364                         }
365
366                         public int Maxargs {
367                                 get { return 2; }
368                         }
369
370                         public int Minargs {
371                                 get { return 2; }
372                         }
373
374                         public XPathResultType ReturnType {
375                                 get { return XPathResultType.String; }
376                         }
377
378                         public object Invoke (XsltContext xsltContext,
379                                 object [] args, XPathNavigator instanceContext)
380                         {
381                                 return ((string) args [0]) [(int) (double) args [1]].ToString ();
382                         }
383                 }
384
385                 public class MyVariable : IXsltContextVariable
386                 {
387                         string name;
388
389                         public MyVariable (string name)
390                         {
391                                 this.name = name;
392                         }
393
394                         public object Evaluate (XsltContext ctx)
395                         {
396                                 return ((MyContext) ctx).GetParam (name, String.Empty);
397                         }
398
399                         public bool IsLocal {
400                                 get { return false; }
401                         }
402
403                         public bool IsParam {
404                                 get { return false; }
405                         }
406
407                         public XPathResultType VariableType {
408                                 get { return XPathResultType.Any; }
409                         }
410                 }
411
412 #if NET_2_0
413                 [Test]
414                 public void ValueAsBoolean ()
415                 {
416                         string xml = "<root>1</root>";
417                         XmlDocument doc = new XmlDocument ();
418                         doc.LoadXml (xml);
419                         XPathNavigator nav = doc.CreateNavigator ();
420                         nav.MoveToFirstChild ();
421                         AssertEquals ("#1", true, nav.ValueAsBoolean);
422                         nav.MoveToFirstChild ();
423                         AssertEquals ("#2", true, nav.ValueAsBoolean);
424                 }
425
426                 [Test]
427                 [ExpectedException (typeof (FormatException))]
428                 public void ValueAsBooleanFail ()
429                 {
430                         string xml = "<root>1.0</root>";
431                         XmlDocument doc = new XmlDocument ();
432                         doc.LoadXml (xml);
433                         XPathNavigator nav = doc.CreateNavigator ();
434                         nav.MoveToFirstChild ();
435                         bool i = nav.ValueAsBoolean;
436                 }
437
438                 [Test]
439                 public void ValueAsDateTime ()
440                 {
441                         DateTime time = new DateTime (2005, 12, 13);
442                         string xml = "<root>2005-12-13</root>";
443                         XmlDocument doc = new XmlDocument ();
444                         doc.LoadXml (xml);
445                         XPathNavigator nav = doc.CreateNavigator ();
446                         nav.MoveToFirstChild ();
447                         AssertEquals ("#1", time, nav.ValueAsDateTime);
448                         nav.MoveToFirstChild ();
449                         AssertEquals ("#2", time, nav.ValueAsDateTime);
450                 }
451
452                 [Test]
453                 [ExpectedException (typeof (FormatException))]
454                 public void ValueAsDateTimeFail ()
455                 {
456                         string xml = "<root>dating time</root>";
457                         XmlDocument doc = new XmlDocument ();
458                         doc.LoadXml (xml);
459                         XPathNavigator nav = doc.CreateNavigator ();
460                         nav.MoveToFirstChild ();
461                         DateTime time = nav.ValueAsDateTime;
462                 }
463
464                 [Test]
465                 public void ValueAsDouble ()
466                 {
467                         string xml = "<root>3.14159265359</root>";
468                         XmlDocument doc = new XmlDocument ();
469                         doc.LoadXml (xml);
470                         XPathNavigator nav = doc.CreateNavigator ();
471                         nav.MoveToFirstChild ();
472                         AssertEquals ("#1", 3.14159265359, nav.ValueAsDouble);
473                         nav.MoveToFirstChild ();
474                         AssertEquals ("#2", 3.14159265359, nav.ValueAsDouble);
475                 }
476
477                 [Test]
478                 [ExpectedException (typeof (FormatException))]
479                 public void ValueAsDoubleFail ()
480                 {
481                         string xml = "<root>Double Dealer</root>";
482                         XmlDocument doc = new XmlDocument ();
483                         doc.LoadXml (xml);
484                         XPathNavigator nav = doc.CreateNavigator ();
485                         nav.MoveToFirstChild ();
486                         Double dealer = nav.ValueAsDouble;
487                 }
488
489                 [Test]
490                 public void ValueAsInt ()
491                 {
492                         string xml = "<root>1</root>";
493                         XmlDocument doc = new XmlDocument ();
494                         doc.LoadXml (xml);
495                         XPathNavigator nav = doc.CreateNavigator ();
496                         nav.MoveToFirstChild ();
497                         AssertEquals ("#1", 1, nav.ValueAsInt);
498                         nav.MoveToFirstChild ();
499                         AssertEquals ("#2", 1, nav.ValueAsInt);
500                 }
501
502                 [Test]
503                 // Here, it seems to be using XQueryConvert (whatever was called)
504                 [ExpectedException (typeof (FormatException))]
505                 public void ValueAsIntFail ()
506                 {
507                         string xml = "<root>1.0</root>";
508                         XmlDocument doc = new XmlDocument ();
509                         doc.LoadXml (xml);
510                         XPathNavigator nav = doc.CreateNavigator ();
511                         nav.MoveToFirstChild ();
512                         int i = nav.ValueAsInt;
513                 }
514
515                 [Test]
516                 public void ValueAsLong ()
517                 {
518                         string xml = "<root>10000000000000000</root>";
519                         XmlDocument doc = new XmlDocument ();
520                         doc.LoadXml (xml);
521                         XPathNavigator nav = doc.CreateNavigator ();
522                         nav.MoveToFirstChild ();
523                         AssertEquals ("#1", 10000000000000000, nav.ValueAsLong);
524                         nav.MoveToFirstChild ();
525                         AssertEquals ("#2", 10000000000000000, nav.ValueAsLong);
526                 }
527
528                 [Test]
529                 // Here, it seems to be using XQueryConvert (whatever was called)
530                 [ExpectedException (typeof (FormatException))]
531                 public void ValueAsLongFail ()
532                 {
533                         string xml = "<root>0x10000000000000000</root>";
534                         XmlDocument doc = new XmlDocument ();
535                         doc.LoadXml (xml);
536                         XPathNavigator nav = doc.CreateNavigator ();
537                         nav.MoveToFirstChild ();
538                         long l = nav.ValueAsLong;
539                 }
540
541                 [Test] // bug #79874
542                 public void InnerXmlText ()
543                 {
544                         StringReader sr = new StringReader ("<Abc><Foo>Hello</Foo></Abc>");
545                         XPathDocument doc = new XPathDocument (sr);
546                         XPathNavigator nav = doc.CreateNavigator ();
547                         XPathNodeIterator iter = nav.Select ("/Abc/Foo");
548                         iter.MoveNext ();
549                         AssertEquals ("#1", "Hello", iter.Current.InnerXml);
550                         AssertEquals ("#2", "<Foo>Hello</Foo>", iter.Current.OuterXml);
551                         iter = nav.Select ("/Abc/Foo/text()");
552                         iter.MoveNext ();
553                         AssertEquals ("#3", String.Empty, iter.Current.InnerXml);
554                         AssertEquals ("#4", "Hello", iter.Current.OuterXml);
555                 }
556
557                 [Test] // bug #79875
558                 public void InnerXmlAttribute ()
559                 {
560                         StringReader sr = new StringReader ("<Abc><Foo attr='val1'/></Abc>");
561                         XPathDocument doc = new XPathDocument (sr);
562                         XPathNavigator nav = doc.CreateNavigator ();
563
564                         XPathNodeIterator iter = nav.Select ("/Abc/Foo/@attr");
565                         iter.MoveNext ();
566                         AssertEquals ("val1", iter.Current.InnerXml);
567                 }
568
569                 [Test]
570                 public void InnerXmlTextEscape ()
571                 {
572                         StringReader sr = new StringReader ("<Abc><Foo>Hello&lt;\r\nInnerXml</Foo></Abc>");
573                         XPathDocument doc = new XPathDocument (sr);
574                         XPathNavigator nav = doc.CreateNavigator ();
575                         XPathNodeIterator iter = nav.Select ("/Abc/Foo");
576                         iter.MoveNext ();
577                         AssertEquals ("#1", "Hello&lt;\r\nInnerXml", iter.Current.InnerXml);
578                         AssertEquals ("#2", "<Foo>Hello&lt;\r\nInnerXml</Foo>", iter.Current.OuterXml);
579                         iter = nav.Select ("/Abc/Foo/text()");
580                         iter.MoveNext ();
581                         AssertEquals ("#3", String.Empty, iter.Current.InnerXml);
582                         AssertEquals ("#4", "Hello&lt;\r\nInnerXml", iter.Current.OuterXml);
583                 }
584
585                 [Test]
586                 [Category ("NotDotNet")] // .NET bug; it should escape value
587                 public void InnerXmlAttributeEscape ()
588                 {
589                         StringReader sr = new StringReader ("<Abc><Foo attr='val&quot;1&#13;&#10;&gt;'/></Abc>");
590                         XPathDocument doc = new XPathDocument (sr);
591                         XPathNavigator nav = doc.CreateNavigator ();
592
593                         XPathNodeIterator iter = nav.Select ("/Abc/Foo/@attr");
594                         iter.MoveNext ();
595                         AssertEquals ("val&quot;1&#10;&gt;", iter.Current.InnerXml);
596                 }
597
598                 [Test]
599                 public void WriterAttributePrefix ()
600                 {
601                         XmlDocument doc = new XmlDocument ();
602                         XmlWriter w = doc.CreateNavigator ().AppendChild ();
603                         w.WriteStartElement ("foo");
604                         w.WriteAttributeString ("xmlns", "x", "http://www.w3.org/2000/xmlns/", "urn:foo");
605                         AssertEquals ("#0", "x", w.LookupPrefix ("urn:foo"));
606                         w.WriteStartElement (null, "bar", "urn:foo");
607                         w.WriteAttributeString (null, "ext", "urn:foo", "bah");
608                         w.WriteEndElement ();
609                         w.WriteEndElement ();
610                         w.Close ();
611                         AssertEquals ("#1", "x", doc.FirstChild.FirstChild.Prefix);
612                         AssertEquals ("#2", "x", doc.FirstChild.FirstChild.Attributes [0].Prefix);
613                 }
614 #endif
615         }
616 }