Fix bug #2383 patch by Weeble - in XPathExtensions.Evaluate(), return IEnumerable...
[mono-project.git] / mcs / class / System.Xml.Linq / Test / System.Xml.XPath / ExtensionsTest.cs
blob93d64290bedb10fbbbc6c6656947330678eb441d
1 //
2 // Author:
3 // Atsushi Enomoto <atsushi@ximian.com>
4 //
5 // Copyright (C) 2010 Novell, Inc.
6 // (C) 2003 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 // (based on XPathNavigatorCommonTests)
32 using System;
33 using System.Collections;
34 using System.IO;
35 using System.Linq;
36 using System.Xml;
37 using System.Xml.Linq;
38 using System.Xml.XPath;
39 using NUnit.Framework;
41 namespace MonoTests.System.Xml
43 [TestFixture]
44 public class ExtensionsTest
46 XPathNavigator nav;
48 private void AssertNavigator (string label, XPathNavigator nav, XPathNodeType type, string prefix, string localName, string ns, string name, string value, bool hasAttributes, bool hasChildren, bool isEmptyElement)
50 label += nav.GetType ();
51 Assert.AreEqual (type, nav.NodeType, label + "NodeType");
52 Assert.AreEqual (prefix, nav.Prefix, label + "Prefix");
53 Assert.AreEqual (localName, nav.LocalName, label + "LocalName");
54 Assert.AreEqual (ns, nav.NamespaceURI, label + "Namespace");
55 Assert.AreEqual (name, nav.Name, label + "Name");
56 Assert.AreEqual (value, nav.Value, label + "Value");
57 Assert.AreEqual (hasAttributes, nav.HasAttributes, label + "HasAttributes");
58 Assert.AreEqual (hasChildren, nav.HasChildren, label + "HasChildren");
59 Assert.AreEqual (isEmptyElement, nav.IsEmptyElement, label + "IsEmptyElement");
62 [Test]
63 public void DocumentWithXmlDeclaration ()
65 string xml = "<?xml version=\"1.0\" standalone=\"yes\"?><foo>bar</foo>";
67 nav = XDocument.Parse (xml).CreateNavigator ();
68 DocumentWithXmlDeclaration (nav);
71 public void DocumentWithXmlDeclaration (XPathNavigator nav)
73 nav.MoveToFirstChild ();
74 AssertNavigator ("#1", nav, XPathNodeType.Element, "", "foo", "", "foo", "bar", false, true, false);
77 [Test]
78 public void DocumentWithProcessingInstruction ()
80 string xml = "<?xml-stylesheet href='foo.xsl' type='text/xsl' ?><foo />";
82 nav = XDocument.Parse (xml).CreateNavigator ();
83 DocumentWithProcessingInstruction (nav);
86 public void DocumentWithProcessingInstruction (XPathNavigator nav)
88 Assert.IsTrue (nav.MoveToFirstChild ());
89 AssertNavigator ("#1", nav, XPathNodeType.ProcessingInstruction, "", "xml-stylesheet", "", "xml-stylesheet", "href='foo.xsl' type='text/xsl' ", false, false, false);
90 Assert.IsTrue (!nav.MoveToFirstChild ());
93 [Test]
94 public void XmlRootElementOnly ()
96 string xml = "<foo />";
98 nav = XDocument.Parse (xml).CreateNavigator ();
99 XmlRootElementOnly (nav);
102 private void XmlRootElementOnly (XPathNavigator nav)
104 AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
105 Assert.IsTrue (nav.MoveToFirstChild ());
106 AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, false, true);
107 Assert.IsTrue (!nav.MoveToFirstChild ());
108 Assert.IsTrue (!nav.MoveToNext ());
109 Assert.IsTrue (!nav.MoveToPrevious ());
110 nav.MoveToRoot ();
111 AssertNavigator ("#3", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
112 Assert.IsTrue (!nav.MoveToNext ());
115 [Test]
116 public void XmlSimpleTextContent ()
118 string xml = "<foo>Test.</foo>";
120 nav = XDocument.Parse (xml).CreateNavigator ();
121 XmlSimpleTextContent (nav);
124 private void XmlSimpleTextContent (XPathNavigator nav)
126 AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
127 Assert.IsTrue (nav.MoveToFirstChild (), "#x1");
128 AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
129 Assert.IsTrue (!nav.MoveToNext (), "#x2");
130 Assert.IsTrue (!nav.MoveToPrevious (), "#x3");
131 Assert.IsTrue (nav.MoveToFirstChild (), "#x4");
132 AssertNavigator ("#3", nav, XPathNodeType.Text, "", "", "", "", "Test.", false, false, false);
134 Assert.IsTrue (nav.MoveToParent (), "#x5");
135 AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
137 Assert.IsTrue (nav.MoveToParent (), "#x6");
138 AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
140 nav.MoveToFirstChild ();
141 nav.MoveToFirstChild ();
142 nav.MoveToRoot ();
143 AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
144 Assert.IsTrue (!nav.MoveToNext (), "#x7");
147 [Test]
148 public void XmlSimpleElementContent ()
150 string xml = "<foo><bar /></foo>";
152 nav = XDocument.Parse (xml).CreateNavigator ();
153 XmlSimpleElementContent (nav);
156 private void XmlSimpleElementContent (XPathNavigator nav)
158 AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
159 Assert.IsTrue (nav.MoveToFirstChild ());
160 AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
161 Assert.IsTrue (!nav.MoveToNext ());
162 Assert.IsTrue (!nav.MoveToPrevious ());
164 Assert.IsTrue (nav.MoveToFirstChild ());
165 AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
167 Assert.IsTrue (nav.MoveToParent ());
168 AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
170 nav.MoveToRoot ();
171 AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
172 Assert.IsTrue (!nav.MoveToNext ());
175 [Test]
176 public void XmlTwoElementsContent ()
178 string xml = "<foo><bar /><baz /></foo>";
180 nav = XDocument.Parse (xml).CreateNavigator ();
181 XmlTwoElementsContent (nav);
184 private void XmlTwoElementsContent (XPathNavigator nav)
186 AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
188 Assert.IsTrue (nav.MoveToFirstChild ());
189 AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
190 Assert.IsTrue (!nav.MoveToNext ());
191 Assert.IsTrue (!nav.MoveToPrevious ());
193 Assert.IsTrue (nav.MoveToFirstChild ());
194 AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
195 Assert.IsTrue (!nav.MoveToFirstChild ());
197 Assert.IsTrue (nav.MoveToNext ());
198 AssertNavigator ("#4", nav, XPathNodeType.Element, "", "baz", "", "baz", "", false, false, true);
199 Assert.IsTrue (!nav.MoveToFirstChild ());
201 Assert.IsTrue (nav.MoveToPrevious ());
202 AssertNavigator ("#5", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
204 nav.MoveToRoot ();
205 AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
206 Assert.IsTrue (!nav.MoveToNext ());
209 [Test]
210 public void XmlElementWithAttributes ()
212 string xml = "<img src='foo.png' alt='image Fooooooo!' />";
214 nav = XDocument.Parse (xml).CreateNavigator ();
215 XmlElementWithAttributes (nav);
218 private void XmlElementWithAttributes (XPathNavigator nav)
220 nav.MoveToFirstChild ();
221 AssertNavigator ("#1", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
222 Assert.IsTrue (!nav.MoveToNext (), "#x1");
223 Assert.IsTrue (!nav.MoveToPrevious (), "#x2");
225 Assert.IsTrue (nav.MoveToFirstAttribute (), "#x3");
226 AssertNavigator ("#2", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
227 Assert.IsTrue (!nav.MoveToFirstAttribute (), "#x4"); // On attributes, it fails.
229 Assert.IsTrue (nav.MoveToNextAttribute (), "#x5");
230 AssertNavigator ("#3", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
231 Assert.IsTrue (!nav.MoveToNextAttribute (), "#x6");
233 Assert.IsTrue (nav.MoveToParent (), "#x7");
234 AssertNavigator ("#4", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
236 Assert.IsTrue (nav.MoveToAttribute ("alt", ""), "#x8");
237 AssertNavigator ("#5", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
238 Assert.IsTrue (!nav.MoveToAttribute ("src", ""), "#x9"); // On attributes, it fails.
239 Assert.IsTrue (nav.MoveToParent (), "#x10");
240 Assert.IsTrue (nav.MoveToAttribute ("src", ""), "#x11");
241 AssertNavigator ("#6", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
243 nav.MoveToRoot ();
244 AssertNavigator ("#7", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
247 [Test]
248 // seems like MS does not want to fix their long-time-known
249 // XPathNavigator bug, so just set it as NotDotNet.
250 // We are better.
251 [Category ("NotDotNet")]
252 public void XmlNamespaceNode ()
254 string xml = "<html xmlns='http://www.w3.org/1999/xhtml'><body>test.</body></html>";
256 nav = XDocument.Parse (xml).CreateNavigator ();
257 XmlNamespaceNode (nav);
260 private void XmlNamespaceNode (XPathNavigator nav)
262 string xhtml = "http://www.w3.org/1999/xhtml";
263 string xmlNS = "http://www.w3.org/XML/1998/namespace";
264 nav.MoveToFirstChild ();
265 AssertNavigator ("#1", nav, XPathNodeType.Element,
266 "", "html", xhtml, "html", "test.", false, true, false);
267 Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.Local));
268 AssertNavigator ("#2", nav, XPathNodeType.Namespace,
269 "", "", "", "", xhtml, false, false, false);
271 // Test difference between Local, ExcludeXml and All.
272 Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.Local));
273 Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.ExcludeXml));
274 // LAMESPEC: MS.NET 1.0 XmlDocument seems to have some bugs around here.
275 // see http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316808
276 #if true
277 Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
278 AssertNavigator ("#3", nav, XPathNodeType.Namespace,
279 "", "xml", "", "xml", xmlNS, false, false, false);
280 Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.All));
281 #endif
282 // Test to check if MoveToRoot() resets Namespace node status.
283 nav.MoveToRoot ();
284 AssertNavigator ("#4", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
285 nav.MoveToFirstChild ();
287 // Test without XPathNamespaceScope argument.
288 Assert.IsTrue (nav.MoveToFirstNamespace ());
289 Assert.IsTrue (nav.MoveToNextNamespace ());
290 AssertNavigator ("#5", nav, XPathNodeType.Namespace,
291 "", "xml", "", "xml", xmlNS, false, false, false);
293 // Test MoveToParent()
294 Assert.IsTrue (nav.MoveToParent ());
295 AssertNavigator ("#6", nav, XPathNodeType.Element,
296 "", "html", xhtml, "html", "test.", false, true, false);
298 nav.MoveToFirstChild (); // body
299 // Test difference between Local and ExcludeXml
300 Assert.IsTrue (!nav.MoveToFirstNamespace (XPathNamespaceScope.Local), "Local should fail");
301 Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml), "ExcludeXml should succeed");
302 AssertNavigator ("#7", nav, XPathNodeType.Namespace,
303 "", "", "", "", xhtml, false, false, false);
305 Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
306 AssertNavigator ("#8", nav, XPathNodeType.Namespace,
307 "", "xml", "", "xml", xmlNS, false, false, false);
308 Assert.IsTrue (nav.MoveToParent ());
309 AssertNavigator ("#9", nav, XPathNodeType.Element,
310 "", "body", xhtml, "body", "test.", false, true, false);
312 nav.MoveToRoot ();
313 AssertNavigator ("#10", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
316 [Test]
317 public void MoveToNamespaces ()
319 string xml = "<a xmlns:x='urn:x'><b xmlns:y='urn:y'/><c/><d><e attr='a'/></d></a>";
321 nav = XDocument.Parse (xml).CreateNavigator ();
322 MoveToNamespaces (nav);
325 private void MoveToNamespaces (XPathNavigator nav)
327 XPathNodeIterator iter = nav.Select ("//e");
328 iter.MoveNext ();
329 nav.MoveTo (iter.Current);
330 Assert.AreEqual ("e", nav.Name, "#1");
331 nav.MoveToFirstNamespace ();
332 Assert.AreEqual ("x", nav.Name, "#2");
333 nav.MoveToNextNamespace ();
334 Assert.AreEqual ("xml", nav.Name, "#3");
337 [Test]
338 public void IsDescendant ()
340 string xml = "<a><b/><c/><d><e attr='a'/></d></a>";
342 nav = XDocument.Parse (xml).CreateNavigator ();
343 IsDescendant (nav);
346 private void IsDescendant (XPathNavigator nav)
348 XPathNavigator tmp = nav.Clone ();
349 XPathNodeIterator iter = nav.Select ("//e");
350 iter.MoveNext ();
351 Assert.IsTrue (nav.MoveTo (iter.Current), "#1");
352 Assert.IsTrue (nav.MoveToFirstAttribute (), "#2");
353 Assert.AreEqual ("attr", nav.Name, "#3");
354 Assert.AreEqual ("", tmp.Name, "#4");
355 Assert.IsTrue (tmp.IsDescendant (nav), "#5");
356 Assert.IsTrue (!nav.IsDescendant (tmp), "#6");
357 tmp.MoveToFirstChild ();
358 Assert.AreEqual ("a", tmp.Name, "#7");
359 Assert.IsTrue (tmp.IsDescendant (nav), "#8");
360 Assert.IsTrue (!nav.IsDescendant (tmp), "#9");
361 tmp.MoveTo (iter.Current);
362 Assert.AreEqual ("e", tmp.Name, "#10");
363 Assert.IsTrue (tmp.IsDescendant (nav), "#11");
364 Assert.IsTrue (!nav.IsDescendant (tmp), "#12");
367 [Test]
368 public void LiterallySplitText ()
370 string xml = "<root><![CDATA[test]]> string</root>";
372 nav = XDocument.Parse (xml).CreateNavigator ();
373 LiterallySplitText (nav);
376 private void LiterallySplitText (XPathNavigator nav)
378 nav.MoveToFirstChild ();
379 nav.MoveToFirstChild ();
380 Assert.AreEqual (XPathNodeType.Text, nav.NodeType, "#1");
381 Assert.AreEqual ("test string", nav.Value, "#2");
384 // bug #75609
385 [Test]
386 public void SelectChildren ()
388 string xml = "<root><foo xmlns='urn:foo' /><ns:foo xmlns:ns='urn:foo' /></root>";
390 nav = XDocument.Parse (xml).CreateNavigator ();
391 SelectChildrenNS (nav);
394 private void SelectChildrenNS (XPathNavigator nav)
396 nav.MoveToFirstChild (); // root
397 XPathNodeIterator iter = nav.SelectChildren ("foo", "urn:foo");
398 Assert.AreEqual (2, iter.Count, "#1");
401 #if NET_2_0
403 [Test]
404 // bug #78067
405 public void OuterXml ()
407 string xml = @"<?xml version=""1.0""?>
408 <one>
409 <two>Some data.</two>
410 </one>";
412 nav = XDocument.Parse (xml).CreateNavigator ();
413 OuterXml (nav);
416 private void OuterXml (XPathNavigator nav)
418 string ret = @"<one>
419 <two>Some data.</two>
420 </one>";
421 Assert.AreEqual (ret, nav.OuterXml.Replace ("\r\n", "\n"), "#1");
424 [Test]
425 public void ReadSubtreeLookupNamespace ()
427 string xml = "<x:foo xmlns:x='urn:x'><bar>x:val</bar></x:foo>";
428 var doc = new XmlDocument ();
429 doc.LoadXml (xml);
430 XPathNavigator nav = doc.LastChild.LastChild.CreateNavigator ();
431 var xr = nav.ReadSubtree ();
432 xr.MoveToContent ();
433 xr.Read (); // should be at x:val
434 Assert.AreEqual ("urn:x", xr.LookupNamespace ("x"), "#1");
436 #endif
438 [Test]
439 public void GetNamespaceConsistentTree ()
441 string xml = "<x:root xmlns:x='urn:x'> <x:foo xmlns='ns1'> <x:bar /> </x:foo> <x:foo xmlns:y='ns2'> <x:bar /> </x:foo></x:root>";
442 nav = XDocument.Parse (xml).CreateNavigator ();
443 GetNamespaceConsistentTree (nav);
446 private void GetNamespaceConsistentTree (XPathNavigator nav)
448 nav.MoveToFirstChild ();
449 nav.MoveToFirstChild ();
450 nav.MoveToNext ();
451 Assert.AreEqual (String.Empty, nav.GetNamespace (""), "#1." + nav.GetType ());
452 nav.MoveToNext ();
453 nav.MoveToNext ();
454 Assert.AreEqual ("", nav.GetNamespace (""), "#2." + nav.GetType ());
457 [Test] // bug #2383
458 public void EvaluateNodeSetAsEnumerable ()
460 String xml = "<root a='value'/>";
461 XDocument d = XDocument.Parse (xml);
462 IEnumerable att = (IEnumerable) d.XPathEvaluate ("/root/@a");
463 att.Cast<XAttribute> ().FirstOrDefault ();