1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.IO; 6 using System.Linq; 7 using System.Xml; 8 using System.Xml.Linq; 9 using Microsoft.Test.ModuleCore; 10 11 namespace CoreXml.Test.XLinq 12 { 13 public partial class FunctionalTests : TestModule 14 { 15 public partial class XNodeReaderTests : XLinqTestCase 16 { 17 public partial class XNodeReaderAPI : XLinqTestCase 18 { 19 // open on different node types, scoping 20 // namespaces ... 21 // read subtree (scoping) 22 // adjacent text nodes 23 24 private string _xml = "<?xml version='1.0'?>\t<A><?PI?><!--comment1--><B xmlns='x' xmlns:p='nsp'>some_text<C/><?PIX click?><D xmlns='y'/><!--comm2--><p:E/></B></A>"; 25 26 //[Variation(Priority = 1, Desc = "Open on node type: XElement (root)", Params = new object[] { XmlNodeType.Element, 0, new string[] { "A", "", "" }, 15 })] 27 //[Variation(Priority = 0, Desc = "Open on node type: XElement (in the mIddle)", Params = new object[] { XmlNodeType.Element, 1, new string[] { "B", "", "x" }, 11 })] 28 //[Variation(Priority = 0, Desc = "Open on node type: XElement (leaf I.)", Params = new object[] { XmlNodeType.Element, 3, new string[] { "D", "", "y" }, 2 })] 29 //[Variation(Priority = 1, Desc = "Open on node type: XElement (leaf II.)", Params = new object[] { XmlNodeType.Element, 4, new string[] { "E", "p", "nsp" }, 1 })] 30 //[Variation(Priority = 2, Desc = "Open on node type: PI (root level)", Params = new object[] { XmlNodeType.ProcessingInstruction, 0, new string[] { "PI", "" }, 1 })] 31 //[Variation(Priority = 2, Desc = "Open on node type: PI", Params = new object[] { XmlNodeType.ProcessingInstruction, 1, new string[] { "PIX", "click" }, 1 })] 32 //[Variation(Priority = 2, Desc = "Open on node type: Comment (root level)", Params = new object[] { XmlNodeType.Comment, 0, new string[] { "comment1" }, 1 })] 33 //[Variation(Priority = 2, Desc = "Open on node type: Comment", Params = new object[] { XmlNodeType.Comment, 1, new string[] { "comm2" }, 1 })] 34 //[Variation(Priority = 0, Desc = "Open on node type: Text (root level)", Params = new object[] { XmlNodeType.Text, 0, new string[] { "\t" }, 1 })] 35 //[Variation(Priority = 1, Desc = "Open on node type: Text", Params = new object[] { XmlNodeType.Text, 1, new string[] { "some_text" }, 1 })] OpenOnNodeType()36 public void OpenOnNodeType() 37 { 38 XmlNodeType nodeType = (XmlNodeType)Variation.Params[0]; 39 int position = (int)Variation.Params[1]; 40 string[] verif = (string[])Variation.Params[2]; 41 int HowManyReads = (int)Variation.Params[3]; 42 43 XDocument doc = XDocument.Load(new StringReader(_xml), LoadOptions.PreserveWhitespace); 44 45 // Navigate to the required node 46 int count = 0; 47 XNode node = null; 48 foreach (XNode n in doc.DescendantNodes().Where(x => x.NodeType == nodeType)) 49 { 50 if (position == count) 51 { 52 node = n; 53 break; 54 } 55 count++; 56 } 57 58 using (XmlReader r = node.CreateReader()) 59 { 60 TestLog.Compare(r.ReadState, ReadState.Initial, "r.ReadState before Read()"); 61 r.Read(); 62 TestLog.Compare(r.ReadState, ReadState.Interactive, "r.ReadState after Read()"); 63 TestLog.Compare(r.NodeType, (nodeType == XmlNodeType.Text && count == 0) ? XmlNodeType.Whitespace : nodeType, "r.NodeType"); // 64 switch (nodeType) 65 { 66 case XmlNodeType.Element: 67 TestLog.Compare(r.LocalName, verif[0], "r.LocalName"); 68 TestLog.Compare(r.Prefix, verif[1], "r.Prefix"); 69 TestLog.Compare(r.NamespaceURI, verif[2], "r.NamespaceURI"); 70 break; 71 case XmlNodeType.ProcessingInstruction: 72 TestLog.Compare(r.LocalName, verif[0], "r.LocalName"); 73 TestLog.Compare(r.Value, verif[1], "r.Value"); 74 break; 75 case XmlNodeType.Comment: 76 case XmlNodeType.Text: 77 TestLog.Compare(r.Value, verif[0], "r.Value"); 78 break; 79 } 80 int nodeWalkCount = 0; 81 do 82 { 83 nodeWalkCount++; 84 while (r.MoveToNextAttribute()) nodeWalkCount++; 85 } while (r.Read()); 86 TestLog.Compare(r.ReadState, ReadState.EndOfFile, "r.ReadState after reading all"); 87 } 88 } 89 90 //[Variation(Desc = "Namespaces - root element", Params = new object[] { XmlNodeType.Element, 0, new string[] { "", "" } })] 91 //[Variation(Desc = "Namespaces - element", Params = new object[] { XmlNodeType.Element, 1, new string[] { "", "x" }, new string[] { "p", "nsp" } })] 92 //[Variation(Desc = "Namespaces - Comment", Params = new object[] { XmlNodeType.Comment, 1, new string[] { "", "x" }, new string[] { "p", "nsp" } })] 93 //[Variation(Desc = "Namespaces - element, def. ns redef", Params = new object[] { XmlNodeType.Element, 3, new string[] { "", "y" }, new string[] { "p", "nsp" } })] Namespaces()94 public void Namespaces() 95 { 96 XmlNodeType nodeType = (XmlNodeType)Variation.Params[0]; 97 int position = (int)Variation.Params[1]; 98 string[][] namespaces = new string[Variation.Params.OfType<string[]>().Count()][]; 99 for (int i = 0; i < Variation.Params.OfType<string[]>().Count(); i++) namespaces[i] = (string[])Variation.Params[2 + i]; 100 101 XDocument doc = XDocument.Load(new StringReader(_xml), LoadOptions.PreserveWhitespace); 102 103 // Navigate to the required node 104 int count = 0; 105 XNode node = null; 106 foreach (XNode n in doc.DescendantNodes().Where(x => x.NodeType == nodeType)) 107 { 108 if (position == count) 109 { 110 node = n; 111 break; 112 } 113 count++; 114 } 115 116 using (XmlReader r = node.CreateReader()) 117 { 118 TestLog.Compare(r.ReadState, ReadState.Initial, "r.ReadState before Read()"); 119 r.Read(); 120 foreach (string[] nspair in namespaces) 121 TestLog.Compare(r.LookupNamespace(nspair[0]), nspair[1], "Namespace mismatch " + nspair[0] + ", " + nspair[1]); 122 } 123 } 124 125 //[Variation(Priority = 0, Desc = "ReadSubtree (sanity)")] ReadSubtreeSanity()126 public void ReadSubtreeSanity() 127 { 128 XDocument doc = XDocument.Load(new StringReader(_xml), LoadOptions.PreserveWhitespace); 129 using (XmlReader r = doc.CreateReader()) 130 { 131 r.Read(); // \t 132 r.Read(); // A 133 r.Read(); // PI 134 r.Read(); // comment 135 r.Read(); // B 136 using (XmlReader rSub = r.ReadSubtree()) 137 { 138 int counter = 0; 139 while (rSub.Read()) 140 { 141 counter++; 142 while (rSub.MoveToNextAttribute()) counter++; 143 } 144 TestLog.Compare(rSub.ReadState, ReadState.EndOfFile, "rSub.ReadState after reading all"); 145 TestLog.Compare(11, counter, "Invalid node count on subtreereader"); 146 } 147 TestLog.Compare(r.NodeType, XmlNodeType.EndElement, "Nodetype after readsubtree - original"); 148 TestLog.Compare(r.LocalName, "B", "Localname after readsubtree - original"); 149 r.Read(); 150 TestLog.Compare(r.NodeType, XmlNodeType.EndElement, "Nodetype after readsubtree + read - original"); 151 TestLog.Compare(r.LocalName, "A", "Localname after readsubtree + read - original"); 152 r.Read(); 153 TestLog.Compare(r.ReadState, ReadState.EndOfFile, "r.ReadState after reading all"); 154 } 155 } 156 157 //[Variation(Priority = 0, Desc = "Adjacent text nodes (sanity I.)")] AdjacentTextNodes1()158 public void AdjacentTextNodes1() 159 { 160 XElement e = new XElement("A", "start"); 161 e.Add(new XText(" cont")); 162 using (XmlReader r = e.CreateReader()) 163 { 164 r.Read(); // A 165 r.Read(); // "start" 166 TestLog.Compare(r.NodeType, XmlNodeType.Text, "first text node"); 167 TestLog.Compare(r.Value, "start", "first text node value"); 168 r.Read(); // "cont" 169 TestLog.Compare(r.NodeType, XmlNodeType.Text, "second text node"); 170 TestLog.Compare(r.Value, " cont", "second text node value"); 171 } 172 } 173 174 175 //[Variation(Priority = 0, Desc = "Adjacent text nodes (sanity II.) : ReadElementContent")] AdjacentTextNodes2()176 public void AdjacentTextNodes2() 177 { 178 XElement e = new XElement("A", new XElement("B", "start")); 179 e.Element("B").Add(new XText(" cont")); 180 using (XmlReader r = e.CreateReader()) 181 { 182 r.Read(); // A 183 r.Read(); // B 184 string content = r.ReadElementContentAsString(); 185 TestLog.Compare(content, "start cont", "content"); 186 TestLog.Compare(r.NodeType, XmlNodeType.EndElement, "nodeType"); 187 } 188 } 189 190 //[Variation(Priority = 0, Desc = "Adjacent text nodes (sanity IV.) : ReadInnerXml")] AdjacentTextNodesI()191 public void AdjacentTextNodesI() 192 { 193 XElement e = new XElement("A", new XElement("B", "start")); 194 e.Element("B").Add(new XText(" cont")); 195 using (XmlReader r = e.CreateReader()) 196 { 197 r.Read(); // A 198 r.Read(); // B 199 string content = r.ReadInnerXml(); 200 TestLog.Compare(content, "start cont", "content"); 201 TestLog.Compare(r.NodeType, XmlNodeType.EndElement, "nodeType"); 202 } 203 } 204 205 //[Variation(Priority = 0, Desc = "Adjacent text nodes (sanity III.) : ReadContent")] AdjacentTextNodes3()206 public void AdjacentTextNodes3() 207 { 208 XElement e = new XElement("A", new XElement("B", "start")); 209 e.Element("B").Add(new XText(" cont")); 210 using (XmlReader r = e.CreateReader()) 211 { 212 r.Read(); // A 213 r.Read(); // B 214 r.Read(); // "start" 215 TestLog.Compare(r.Value, "start", "r.Value on first text node"); 216 string content = r.ReadContentAsString(); 217 TestLog.Compare(content, "start cont", "content"); 218 TestLog.Compare(r.NodeType, XmlNodeType.EndElement, "nodeType"); 219 } 220 } 221 } 222 } 223 } 224 } 225