ExtensionsTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. //
  2. // Author:
  3. // Atsushi Enomoto <[email protected]>
  4. //
  5. // Copyright (C) 2010 Novell, Inc.
  6. // (C) 2003 Atsushi Enomoto <[email protected]>
  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.
  26. //
  27. //
  28. // (based on XPathNavigatorCommonTests)
  29. //
  30. using System;
  31. using System.IO;
  32. using System.Linq;
  33. using System.Xml;
  34. using System.Xml.Linq;
  35. using System.Xml.XPath;
  36. using NUnit.Framework;
  37. namespace MonoTests.System.Xml
  38. {
  39. [TestFixture]
  40. public class ExtensionsTest
  41. {
  42. XPathNavigator nav;
  43. 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)
  44. {
  45. label += nav.GetType ();
  46. Assert.AreEqual (type, nav.NodeType, label + "NodeType");
  47. Assert.AreEqual (prefix, nav.Prefix, label + "Prefix");
  48. Assert.AreEqual (localName, nav.LocalName, label + "LocalName");
  49. Assert.AreEqual (ns, nav.NamespaceURI, label + "Namespace");
  50. Assert.AreEqual (name, nav.Name, label + "Name");
  51. Assert.AreEqual (value, nav.Value, label + "Value");
  52. Assert.AreEqual (hasAttributes, nav.HasAttributes, label + "HasAttributes");
  53. Assert.AreEqual (hasChildren, nav.HasChildren, label + "HasChildren");
  54. Assert.AreEqual (isEmptyElement, nav.IsEmptyElement, label + "IsEmptyElement");
  55. }
  56. [Test]
  57. public void DocumentWithXmlDeclaration ()
  58. {
  59. string xml = "<?xml version=\"1.0\" standalone=\"yes\"?><foo>bar</foo>";
  60. nav = XDocument.Parse (xml).CreateNavigator ();
  61. DocumentWithXmlDeclaration (nav);
  62. }
  63. public void DocumentWithXmlDeclaration (XPathNavigator nav)
  64. {
  65. nav.MoveToFirstChild ();
  66. AssertNavigator ("#1", nav, XPathNodeType.Element, "", "foo", "", "foo", "bar", false, true, false);
  67. }
  68. [Test]
  69. public void DocumentWithProcessingInstruction ()
  70. {
  71. string xml = "<?xml-stylesheet href='foo.xsl' type='text/xsl' ?><foo />";
  72. nav = XDocument.Parse (xml).CreateNavigator ();
  73. DocumentWithProcessingInstruction (nav);
  74. }
  75. public void DocumentWithProcessingInstruction (XPathNavigator nav)
  76. {
  77. Assert.IsTrue (nav.MoveToFirstChild ());
  78. AssertNavigator ("#1", nav, XPathNodeType.ProcessingInstruction, "", "xml-stylesheet", "", "xml-stylesheet", "href='foo.xsl' type='text/xsl' ", false, false, false);
  79. Assert.IsTrue (!nav.MoveToFirstChild ());
  80. }
  81. [Test]
  82. public void XmlRootElementOnly ()
  83. {
  84. string xml = "<foo />";
  85. nav = XDocument.Parse (xml).CreateNavigator ();
  86. XmlRootElementOnly (nav);
  87. }
  88. private void XmlRootElementOnly (XPathNavigator nav)
  89. {
  90. AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  91. Assert.IsTrue (nav.MoveToFirstChild ());
  92. AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, false, true);
  93. Assert.IsTrue (!nav.MoveToFirstChild ());
  94. Assert.IsTrue (!nav.MoveToNext ());
  95. Assert.IsTrue (!nav.MoveToPrevious ());
  96. nav.MoveToRoot ();
  97. AssertNavigator ("#3", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  98. Assert.IsTrue (!nav.MoveToNext ());
  99. }
  100. [Test]
  101. public void XmlSimpleTextContent ()
  102. {
  103. string xml = "<foo>Test.</foo>";
  104. nav = XDocument.Parse (xml).CreateNavigator ();
  105. XmlSimpleTextContent (nav);
  106. }
  107. private void XmlSimpleTextContent (XPathNavigator nav)
  108. {
  109. AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
  110. Assert.IsTrue (nav.MoveToFirstChild (), "#x1");
  111. AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
  112. Assert.IsTrue (!nav.MoveToNext (), "#x2");
  113. Assert.IsTrue (!nav.MoveToPrevious (), "#x3");
  114. Assert.IsTrue (nav.MoveToFirstChild (), "#x4");
  115. AssertNavigator ("#3", nav, XPathNodeType.Text, "", "", "", "", "Test.", false, false, false);
  116. Assert.IsTrue (nav.MoveToParent (), "#x5");
  117. AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
  118. Assert.IsTrue (nav.MoveToParent (), "#x6");
  119. AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
  120. nav.MoveToFirstChild ();
  121. nav.MoveToFirstChild ();
  122. nav.MoveToRoot ();
  123. AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
  124. Assert.IsTrue (!nav.MoveToNext (), "#x7");
  125. }
  126. [Test]
  127. public void XmlSimpleElementContent ()
  128. {
  129. string xml = "<foo><bar /></foo>";
  130. nav = XDocument.Parse (xml).CreateNavigator ();
  131. XmlSimpleElementContent (nav);
  132. }
  133. private void XmlSimpleElementContent (XPathNavigator nav)
  134. {
  135. AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  136. Assert.IsTrue (nav.MoveToFirstChild ());
  137. AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
  138. Assert.IsTrue (!nav.MoveToNext ());
  139. Assert.IsTrue (!nav.MoveToPrevious ());
  140. Assert.IsTrue (nav.MoveToFirstChild ());
  141. AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
  142. Assert.IsTrue (nav.MoveToParent ());
  143. AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
  144. nav.MoveToRoot ();
  145. AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  146. Assert.IsTrue (!nav.MoveToNext ());
  147. }
  148. [Test]
  149. public void XmlTwoElementsContent ()
  150. {
  151. string xml = "<foo><bar /><baz /></foo>";
  152. nav = XDocument.Parse (xml).CreateNavigator ();
  153. XmlTwoElementsContent (nav);
  154. }
  155. private void XmlTwoElementsContent (XPathNavigator nav)
  156. {
  157. AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  158. Assert.IsTrue (nav.MoveToFirstChild ());
  159. AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
  160. Assert.IsTrue (!nav.MoveToNext ());
  161. Assert.IsTrue (!nav.MoveToPrevious ());
  162. Assert.IsTrue (nav.MoveToFirstChild ());
  163. AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
  164. Assert.IsTrue (!nav.MoveToFirstChild ());
  165. Assert.IsTrue (nav.MoveToNext ());
  166. AssertNavigator ("#4", nav, XPathNodeType.Element, "", "baz", "", "baz", "", false, false, true);
  167. Assert.IsTrue (!nav.MoveToFirstChild ());
  168. Assert.IsTrue (nav.MoveToPrevious ());
  169. AssertNavigator ("#5", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
  170. nav.MoveToRoot ();
  171. AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  172. Assert.IsTrue (!nav.MoveToNext ());
  173. }
  174. [Test]
  175. public void XmlElementWithAttributes ()
  176. {
  177. string xml = "<img src='foo.png' alt='image Fooooooo!' />";
  178. nav = XDocument.Parse (xml).CreateNavigator ();
  179. XmlElementWithAttributes (nav);
  180. }
  181. private void XmlElementWithAttributes (XPathNavigator nav)
  182. {
  183. nav.MoveToFirstChild ();
  184. AssertNavigator ("#1", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
  185. Assert.IsTrue (!nav.MoveToNext (), "#x1");
  186. Assert.IsTrue (!nav.MoveToPrevious (), "#x2");
  187. Assert.IsTrue (nav.MoveToFirstAttribute (), "#x3");
  188. AssertNavigator ("#2", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
  189. Assert.IsTrue (!nav.MoveToFirstAttribute (), "#x4"); // On attributes, it fails.
  190. Assert.IsTrue (nav.MoveToNextAttribute (), "#x5");
  191. AssertNavigator ("#3", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
  192. Assert.IsTrue (!nav.MoveToNextAttribute (), "#x6");
  193. Assert.IsTrue (nav.MoveToParent (), "#x7");
  194. AssertNavigator ("#4", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
  195. Assert.IsTrue (nav.MoveToAttribute ("alt", ""), "#x8");
  196. AssertNavigator ("#5", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
  197. Assert.IsTrue (!nav.MoveToAttribute ("src", ""), "#x9"); // On attributes, it fails.
  198. Assert.IsTrue (nav.MoveToParent (), "#x10");
  199. Assert.IsTrue (nav.MoveToAttribute ("src", ""), "#x11");
  200. AssertNavigator ("#6", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
  201. nav.MoveToRoot ();
  202. AssertNavigator ("#7", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
  203. }
  204. [Test]
  205. // seems like MS does not want to fix their long-time-known
  206. // XPathNavigator bug, so just set it as NotDotNet.
  207. // We are better.
  208. [Category ("NotDotNet")]
  209. public void XmlNamespaceNode ()
  210. {
  211. string xml = "<html xmlns='http://www.w3.org/1999/xhtml'><body>test.</body></html>";
  212. nav = XDocument.Parse (xml).CreateNavigator ();
  213. XmlNamespaceNode (nav);
  214. }
  215. private void XmlNamespaceNode (XPathNavigator nav)
  216. {
  217. string xhtml = "http://www.w3.org/1999/xhtml";
  218. string xmlNS = "http://www.w3.org/XML/1998/namespace";
  219. nav.MoveToFirstChild ();
  220. AssertNavigator ("#1", nav, XPathNodeType.Element,
  221. "", "html", xhtml, "html", "test.", false, true, false);
  222. Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.Local));
  223. AssertNavigator ("#2", nav, XPathNodeType.Namespace,
  224. "", "", "", "", xhtml, false, false, false);
  225. // Test difference between Local, ExcludeXml and All.
  226. Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.Local));
  227. Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.ExcludeXml));
  228. // LAMESPEC: MS.NET 1.0 XmlDocument seems to have some bugs around here.
  229. // see http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316808
  230. #if true
  231. Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
  232. AssertNavigator ("#3", nav, XPathNodeType.Namespace,
  233. "", "xml", "", "xml", xmlNS, false, false, false);
  234. Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.All));
  235. #endif
  236. // Test to check if MoveToRoot() resets Namespace node status.
  237. nav.MoveToRoot ();
  238. AssertNavigator ("#4", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
  239. nav.MoveToFirstChild ();
  240. // Test without XPathNamespaceScope argument.
  241. Assert.IsTrue (nav.MoveToFirstNamespace ());
  242. Assert.IsTrue (nav.MoveToNextNamespace ());
  243. AssertNavigator ("#5", nav, XPathNodeType.Namespace,
  244. "", "xml", "", "xml", xmlNS, false, false, false);
  245. // Test MoveToParent()
  246. Assert.IsTrue (nav.MoveToParent ());
  247. AssertNavigator ("#6", nav, XPathNodeType.Element,
  248. "", "html", xhtml, "html", "test.", false, true, false);
  249. nav.MoveToFirstChild (); // body
  250. // Test difference between Local and ExcludeXml
  251. Assert.IsTrue (!nav.MoveToFirstNamespace (XPathNamespaceScope.Local), "Local should fail");
  252. Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml), "ExcludeXml should succeed");
  253. AssertNavigator ("#7", nav, XPathNodeType.Namespace,
  254. "", "", "", "", xhtml, false, false, false);
  255. Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
  256. AssertNavigator ("#8", nav, XPathNodeType.Namespace,
  257. "", "xml", "", "xml", xmlNS, false, false, false);
  258. Assert.IsTrue (nav.MoveToParent ());
  259. AssertNavigator ("#9", nav, XPathNodeType.Element,
  260. "", "body", xhtml, "body", "test.", false, true, false);
  261. nav.MoveToRoot ();
  262. AssertNavigator ("#10", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
  263. }
  264. [Test]
  265. public void MoveToNamespaces ()
  266. {
  267. string xml = "<a xmlns:x='urn:x'><b xmlns:y='urn:y'/><c/><d><e attr='a'/></d></a>";
  268. nav = XDocument.Parse (xml).CreateNavigator ();
  269. MoveToNamespaces (nav);
  270. }
  271. private void MoveToNamespaces (XPathNavigator nav)
  272. {
  273. XPathNodeIterator iter = nav.Select ("//e");
  274. iter.MoveNext ();
  275. nav.MoveTo (iter.Current);
  276. Assert.AreEqual ("e", nav.Name, "#1");
  277. nav.MoveToFirstNamespace ();
  278. Assert.AreEqual ("x", nav.Name, "#2");
  279. nav.MoveToNextNamespace ();
  280. Assert.AreEqual ("xml", nav.Name, "#3");
  281. }
  282. [Test]
  283. public void IsDescendant ()
  284. {
  285. string xml = "<a><b/><c/><d><e attr='a'/></d></a>";
  286. nav = XDocument.Parse (xml).CreateNavigator ();
  287. IsDescendant (nav);
  288. }
  289. private void IsDescendant (XPathNavigator nav)
  290. {
  291. XPathNavigator tmp = nav.Clone ();
  292. XPathNodeIterator iter = nav.Select ("//e");
  293. iter.MoveNext ();
  294. Assert.IsTrue (nav.MoveTo (iter.Current), "#1");
  295. Assert.IsTrue (nav.MoveToFirstAttribute (), "#2");
  296. Assert.AreEqual ("attr", nav.Name, "#3");
  297. Assert.AreEqual ("", tmp.Name, "#4");
  298. Assert.IsTrue (tmp.IsDescendant (nav), "#5");
  299. Assert.IsTrue (!nav.IsDescendant (tmp), "#6");
  300. tmp.MoveToFirstChild ();
  301. Assert.AreEqual ("a", tmp.Name, "#7");
  302. Assert.IsTrue (tmp.IsDescendant (nav), "#8");
  303. Assert.IsTrue (!nav.IsDescendant (tmp), "#9");
  304. tmp.MoveTo (iter.Current);
  305. Assert.AreEqual ("e", tmp.Name, "#10");
  306. Assert.IsTrue (tmp.IsDescendant (nav), "#11");
  307. Assert.IsTrue (!nav.IsDescendant (tmp), "#12");
  308. }
  309. [Test]
  310. public void LiterallySplitText ()
  311. {
  312. string xml = "<root><![CDATA[test]]> string</root>";
  313. nav = XDocument.Parse (xml).CreateNavigator ();
  314. LiterallySplitText (nav);
  315. }
  316. private void LiterallySplitText (XPathNavigator nav)
  317. {
  318. nav.MoveToFirstChild ();
  319. nav.MoveToFirstChild ();
  320. Assert.AreEqual (XPathNodeType.Text, nav.NodeType, "#1");
  321. Assert.AreEqual ("test string", nav.Value, "#2");
  322. }
  323. // bug #75609
  324. [Test]
  325. public void SelectChildren ()
  326. {
  327. string xml = "<root><foo xmlns='urn:foo' /><ns:foo xmlns:ns='urn:foo' /></root>";
  328. nav = XDocument.Parse (xml).CreateNavigator ();
  329. SelectChildrenNS (nav);
  330. }
  331. private void SelectChildrenNS (XPathNavigator nav)
  332. {
  333. nav.MoveToFirstChild (); // root
  334. XPathNodeIterator iter = nav.SelectChildren ("foo", "urn:foo");
  335. Assert.AreEqual (2, iter.Count, "#1");
  336. }
  337. #if NET_2_0
  338. [Test]
  339. // bug #78067
  340. public void OuterXml ()
  341. {
  342. string xml = @"<?xml version=""1.0""?>
  343. <one>
  344. <two>Some data.</two>
  345. </one>";
  346. nav = XDocument.Parse (xml).CreateNavigator ();
  347. OuterXml (nav);
  348. }
  349. private void OuterXml (XPathNavigator nav)
  350. {
  351. string ret = @"<one>
  352. <two>Some data.</two>
  353. </one>";
  354. Assert.AreEqual (ret, nav.OuterXml.Replace ("\r\n", "\n"), "#1");
  355. }
  356. [Test]
  357. public void ReadSubtreeLookupNamespace ()
  358. {
  359. string xml = "<x:foo xmlns:x='urn:x'><bar>x:val</bar></x:foo>";
  360. var doc = new XmlDocument ();
  361. doc.LoadXml (xml);
  362. XPathNavigator nav = doc.LastChild.LastChild.CreateNavigator ();
  363. var xr = nav.ReadSubtree ();
  364. xr.MoveToContent ();
  365. xr.Read (); // should be at x:val
  366. Assert.AreEqual ("urn:x", xr.LookupNamespace ("x"), "#1");
  367. }
  368. #endif
  369. [Test]
  370. public void GetNamespaceConsistentTree ()
  371. {
  372. 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>";
  373. nav = XDocument.Parse (xml).CreateNavigator ();
  374. GetNamespaceConsistentTree (nav);
  375. }
  376. private void GetNamespaceConsistentTree (XPathNavigator nav)
  377. {
  378. nav.MoveToFirstChild ();
  379. nav.MoveToFirstChild ();
  380. nav.MoveToNext ();
  381. Assert.AreEqual (String.Empty, nav.GetNamespace (""), "#1." + nav.GetType ());
  382. nav.MoveToNext ();
  383. nav.MoveToNext ();
  384. Assert.AreEqual ("", nav.GetNamespace (""), "#2." + nav.GetType ());
  385. }
  386. }
  387. }