// System.Xml.XmlDocumentTests // // Authors: // Jason Diamond // Kral Ferch // Martin Willemoes Hansen // // (C) 2002 Jason Diamond, Kral Ferch // (C) 2003 Martin Willemoes Hansen // using System; using System.Collections; using System.Xml; using System.IO; using System.Text; using NUnit.Framework; namespace MonoTests.System.Xml { [TestFixture] public class XmlDocumentTests : Assertion { private XmlDocument document; private ArrayList eventStrings = new ArrayList(); // These Event* methods support the TestEventNode* Tests in this file. // Most of them are event handlers for the XmlNodeChangedEventHandler // delegate. private void EventStringAdd(string eventName, XmlNodeChangedEventArgs e) { string oldParent = (e.OldParent != null) ? e.OldParent.Name : ""; string newParent = (e.NewParent != null) ? e.NewParent.Name : ""; eventStrings.Add (String.Format ("{0}, {1}, {2}, {3}, {4}", eventName, e.Action.ToString (), e.Node.OuterXml, oldParent, newParent)); } private void EventNodeChanged(Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeChanged", e); } private void EventNodeChanging (Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeChanging", e); } private void EventNodeChangingException (Object sender, XmlNodeChangedEventArgs e) { throw new Exception ("don't change the value."); } private void EventNodeInserted(Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeInserted", e); } private void EventNodeInserting(Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeInserting", e); } private void EventNodeInsertingException(Object sender, XmlNodeChangedEventArgs e) { throw new Exception ("don't insert the element."); } private void EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeRemoved", e); } private void EventNodeRemoving(Object sender, XmlNodeChangedEventArgs e) { EventStringAdd ("NodeRemoving", e); } private void EventNodeRemovingException(Object sender, XmlNodeChangedEventArgs e) { throw new Exception ("don't remove the element."); } [SetUp] public void GetReady () { document = new XmlDocument (); document.PreserveWhitespace = true; } [Test] public void CreateNodeNodeTypeNameEmptyParams () { XmlNode node; try { node = document.CreateNode (null, null, null); Fail ("Expected an ArgumentException to be thrown."); } catch (ArgumentException) {} try { node = document.CreateNode ("attribute", null, null); Fail ("Expected a NullReferenceException to be thrown."); } catch (NullReferenceException) {} try { node = document.CreateNode ("attribute", "", null); Fail ("Expected an ArgumentException to be thrown."); } catch (ArgumentException) {} try { node = document.CreateNode ("element", null, null); Fail ("Expected a NullReferenceException to be thrown."); } catch (NullReferenceException) {} try { node = document.CreateNode ("element", "", null); Fail ("Expected an ArgumentException to be thrown."); } catch (ArgumentException) {} try { node = document.CreateNode ("entityreference", null, null); Fail ("Expected a NullReferenceException to be thrown."); } catch (NullReferenceException) {} } [Test] public void CreateNodeInvalidXmlNodeType () { XmlNode node; try { node = document.CreateNode (XmlNodeType.EndElement, null, null); Fail ("Expected an ArgumentOutOfRangeException to be thrown."); } catch (ArgumentOutOfRangeException) {} try { node = document.CreateNode (XmlNodeType.EndEntity, null, null); Fail ("Expected an ArgumentOutOfRangeException to be thrown."); } catch (ArgumentOutOfRangeException) {} try { node = document.CreateNode (XmlNodeType.Entity, null, null); Fail ("Expected an ArgumentOutOfRangeException to be thrown."); } catch (ArgumentOutOfRangeException) {} try { node = document.CreateNode (XmlNodeType.None, null, null); Fail ("Expected an ArgumentOutOfRangeException to be thrown."); } catch (ArgumentOutOfRangeException) {} try { node = document.CreateNode (XmlNodeType.Notation, null, null); Fail ("Expected an ArgumentOutOfRangeException to be thrown."); } catch (ArgumentOutOfRangeException) {} // TODO: undocumented allowable type. node = document.CreateNode (XmlNodeType.XmlDeclaration, null, null); AssertEquals (XmlNodeType.XmlDeclaration, node.NodeType); } [Test] public void CreateNodeWhichParamIsUsed () { XmlNode node; // No constructor params for Document, DocumentFragment. node = document.CreateNode (XmlNodeType.CDATA, "a", "b", "c"); AssertEquals (String.Empty, ((XmlCDataSection)node).Value); node = document.CreateNode (XmlNodeType.Comment, "a", "b", "c"); AssertEquals (String.Empty, ((XmlComment)node).Value); node = document.CreateNode (XmlNodeType.DocumentType, "a", "b", "c"); AssertNull (((XmlDocumentType)node).Value); // TODO: add this back in to test when it's implemented. // node = document.CreateNode (XmlNodeType.EntityReference, "a", "b", "c"); // AssertNull (((XmlEntityReference)node).Value); // TODO: add this back in to test when it's implemented. // node = document.CreateNode (XmlNodeType.ProcessingInstruction, "a", "b", "c"); // AssertEquals (String.Empty, ((XmlProcessingInstruction)node).Value); node = document.CreateNode (XmlNodeType.SignificantWhitespace, "a", "b", "c"); AssertEquals (String.Empty, ((XmlSignificantWhitespace)node).Value); node = document.CreateNode (XmlNodeType.Text, "a", "b", "c"); AssertEquals (String.Empty, ((XmlText)node).Value); node = document.CreateNode (XmlNodeType.Whitespace, "a", "b", "c"); AssertEquals (String.Empty, ((XmlWhitespace)node).Value); node = document.CreateNode (XmlNodeType.XmlDeclaration, "a", "b", "c"); AssertEquals ("version=\"1.0\"", ((XmlDeclaration)node).Value); } [Test] public void CreateNodeNodeTypeName () { XmlNode node; try { node = document.CreateNode ("foo", null, null); Fail ("Expected an ArgumentException to be thrown."); } catch (ArgumentException) {} node = document.CreateNode("attribute", "foo", null); AssertEquals (XmlNodeType.Attribute, node.NodeType); node = document.CreateNode("cdatasection", null, null); AssertEquals (XmlNodeType.CDATA, node.NodeType); node = document.CreateNode("comment", null, null); AssertEquals (XmlNodeType.Comment, node.NodeType); node = document.CreateNode("document", null, null); AssertEquals (XmlNodeType.Document, node.NodeType); // TODO: test which constructor this ended up calling, // i.e. reuse underlying NameTable or not? // TODO: add this back in to test when it's implemented. node = document.CreateNode("documentfragment", null, null); AssertEquals (XmlNodeType.DocumentFragment, node.NodeType); node = document.CreateNode("documenttype", null, null); AssertEquals (XmlNodeType.DocumentType, node.NodeType); node = document.CreateNode("element", "foo", null); AssertEquals (XmlNodeType.Element, node.NodeType); // TODO: add this back in to test when it's implemented. // ---> It is implemented, but it is LAMESPEC that allows null entity reference name. // node = document.CreateNode("entityreference", "foo", null); // AssertEquals (XmlNodeType.EntityReference, node.NodeType); // LAMESPEC: null PI name is silly. // node = document.CreateNode("processinginstruction", null, null); // AssertEquals (XmlNodeType.ProcessingInstruction, node.NodeType); node = document.CreateNode("significantwhitespace", null, null); AssertEquals (XmlNodeType.SignificantWhitespace, node.NodeType); node = document.CreateNode("text", null, null); AssertEquals (XmlNodeType.Text, node.NodeType); node = document.CreateNode("whitespace", null, null); AssertEquals (XmlNodeType.Whitespace, node.NodeType); } [Test] public void DocumentElement () { AssertNull (document.DocumentElement); XmlElement element = document.CreateElement ("foo", "bar", "http://foo/"); AssertNotNull (element); AssertEquals ("foo", element.Prefix); AssertEquals ("bar", element.LocalName); AssertEquals ("http://foo/", element.NamespaceURI); AssertEquals ("foo:bar", element.Name); AssertSame (element, document.AppendChild (element)); AssertSame (element, document.DocumentElement); } [Test] public void DocumentEmpty() { AssertEquals ("Incorrect output for empty document.", "", document.OuterXml); } [Test] public void EventNodeChanged() { XmlElement element; XmlComment comment; document.NodeChanged += new XmlNodeChangedEventHandler (this.EventNodeChanged); // Node that is part of the document. document.AppendChild (document.CreateElement ("foo")); comment = document.CreateComment ("bar"); document.DocumentElement.AppendChild (comment); AssertEquals ("", document.DocumentElement.InnerXml); comment.Value = "baz"; Assert (eventStrings.Contains ("NodeChanged, Change, , foo, foo")); AssertEquals ("", document.DocumentElement.InnerXml); // Node that isn't part of the document but created by the document. element = document.CreateElement ("foo"); comment = document.CreateComment ("bar"); element.AppendChild (comment); AssertEquals ("", element.InnerXml); comment.Value = "baz"; Assert (eventStrings.Contains ("NodeChanged, Change, , foo, foo")); AssertEquals ("", element.InnerXml); /* TODO: Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented. // Node that is part of the document. element = document.CreateElement ("foo"); element.InnerText = "bar"; document.AppendChild(element); element.InnerText = "baz"; Assert(eventStrings.Contains("NodeChanged, Change, baz, foo, foo")); // Node that isn't part of the document but created by the document. element = document.CreateElement("qux"); element.InnerText = "quux"; element.InnerText = "quuux"; Assert(eventStrings.Contains("NodeChanged, Change, quuux, qux, qux")); */ } [Test] public void EventNodeChanging() { XmlElement element; XmlComment comment; document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChanging); // Node that is part of the document. document.AppendChild (document.CreateElement ("foo")); comment = document.CreateComment ("bar"); document.DocumentElement.AppendChild (comment); AssertEquals ("", document.DocumentElement.InnerXml); comment.Value = "baz"; Assert (eventStrings.Contains ("NodeChanging, Change, , foo, foo")); AssertEquals ("", document.DocumentElement.InnerXml); // Node that isn't part of the document but created by the document. element = document.CreateElement ("foo"); comment = document.CreateComment ("bar"); element.AppendChild (comment); AssertEquals ("", element.InnerXml); comment.Value = "baz"; Assert (eventStrings.Contains ("NodeChanging, Change, , foo, foo")); AssertEquals ("", element.InnerXml); // If an exception is thrown the Document returns to original state. document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException); element = document.CreateElement("foo"); comment = document.CreateComment ("bar"); element.AppendChild (comment); AssertEquals ("", element.InnerXml); try { comment.Value = "baz"; Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException()."); } catch (Exception) {} AssertEquals ("", element.InnerXml); // Yes it's a bit anal but this tests whether the node changing event exception fires before the // ArgumentOutOfRangeException. Turns out it does so that means our implementation needs to raise // the node changing event before doing any work. try { comment.ReplaceData(-1, 0, "qux"); Fail("Expected an ArgumentOutOfRangeException to be thrown."); } catch (Exception) {} /* TODO: Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented. // Node that is part of the document. element = document.CreateElement ("foo"); element.InnerText = "bar"; document.AppendChild(element); element.InnerText = "baz"; Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo")); // Node that isn't part of the document but created by the document. element = document.CreateElement("foo"); element.InnerText = "bar"; element.InnerText = "baz"; Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo")); // If an exception is thrown the Document returns to original state. document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException); element = document.CreateElement("foo"); element.InnerText = "bar"; try { element.InnerText = "baz"; Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException()."); } catch (Exception) {} AssertEquals("bar", element.InnerText); */ } [Test] public void EventNodeInserted() { XmlElement element; document.NodeInserted += new XmlNodeChangedEventHandler (this.EventNodeInserted); // Inserted 'foo' element to the document. element = document.CreateElement ("foo"); document.AppendChild (element); Assert (eventStrings.Contains ("NodeInserted, Insert, , , #document")); // Append child on node in document element = document.CreateElement ("foo"); document.DocumentElement.AppendChild (element); Assert (eventStrings.Contains ("NodeInserted, Insert, , , foo")); // Append child on node not in document but created by document element = document.CreateElement ("bar"); element.AppendChild(document.CreateElement ("bar")); Assert(eventStrings.Contains("NodeInserted, Insert, , , bar")); } [Test] public void EventNodeInserting() { XmlElement element; document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInserting); // Inserting 'foo' element to the document. element = document.CreateElement ("foo"); document.AppendChild (element); Assert (eventStrings.Contains ("NodeInserting, Insert, , , #document")); // Append child on node in document element = document.CreateElement ("foo"); document.DocumentElement.AppendChild (element); Assert(eventStrings.Contains ("NodeInserting, Insert, , , foo")); // Append child on node not in document but created by document element = document.CreateElement ("bar"); AssertEquals (0, element.ChildNodes.Count); element.AppendChild (document.CreateElement ("bar")); Assert (eventStrings.Contains ("NodeInserting, Insert, , , bar")); AssertEquals (1, element.ChildNodes.Count); // If an exception is thrown the Document returns to original state. document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInsertingException); AssertEquals (1, element.ChildNodes.Count); try { element.AppendChild (document.CreateElement("baz")); Fail ("Expected an exception to be thrown by the NodeInserting event handler method EventNodeInsertingException()."); } catch (Exception) {} AssertEquals (1, element.ChildNodes.Count); } [Test] public void EventNodeRemoved() { XmlElement element; XmlElement element2; document.NodeRemoved += new XmlNodeChangedEventHandler (this.EventNodeRemoved); // Removed 'bar' element from 'foo' outside document. element = document.CreateElement ("foo"); element2 = document.CreateElement ("bar"); element.AppendChild (element2); AssertEquals (1, element.ChildNodes.Count); element.RemoveChild (element2); Assert (eventStrings.Contains ("NodeRemoved, Remove, , foo, ")); AssertEquals (0, element.ChildNodes.Count); /* * TODO: put this test back in when AttributeCollection.RemoveAll() is implemented. // RemoveAll. element = document.CreateElement ("foo"); element2 = document.CreateElement ("bar"); element.AppendChild(element2); AssertEquals(1, element.ChildNodes.Count); element.RemoveAll(); Assert (eventStrings.Contains ("NodeRemoved, Remove, , foo, ")); AssertEquals(0, element.ChildNodes.Count); */ // Removed 'bar' element from 'foo' inside document. element = document.CreateElement ("foo"); document.AppendChild (element); element = document.CreateElement ("bar"); document.DocumentElement.AppendChild (element); AssertEquals (1, document.DocumentElement.ChildNodes.Count); document.DocumentElement.RemoveChild (element); Assert (eventStrings.Contains ("NodeRemoved, Remove, , foo, ")); AssertEquals (0, document.DocumentElement.ChildNodes.Count); } [Test] public void EventNodeRemoving() { XmlElement element; XmlElement element2; document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemoving); // Removing 'bar' element from 'foo' outside document. element = document.CreateElement ("foo"); element2 = document.CreateElement ("bar"); element.AppendChild (element2); AssertEquals (1, element.ChildNodes.Count); element.RemoveChild (element2); Assert (eventStrings.Contains ("NodeRemoving, Remove, , foo, ")); AssertEquals (0, element.ChildNodes.Count); /* * TODO: put this test back in when AttributeCollection.RemoveAll() is implemented. // RemoveAll. element = document.CreateElement ("foo"); element2 = document.CreateElement ("bar"); element.AppendChild(element2); AssertEquals(1, element.ChildNodes.Count); element.RemoveAll(); Assert (eventStrings.Contains ("NodeRemoving, Remove, , foo, ")); AssertEquals(0, element.ChildNodes.Count); */ // Removing 'bar' element from 'foo' inside document. element = document.CreateElement ("foo"); document.AppendChild (element); element = document.CreateElement ("bar"); document.DocumentElement.AppendChild (element); AssertEquals (1, document.DocumentElement.ChildNodes.Count); document.DocumentElement.RemoveChild (element); Assert (eventStrings.Contains ("NodeRemoving, Remove, , foo, ")); AssertEquals (0, document.DocumentElement.ChildNodes.Count); // If an exception is thrown the Document returns to original state. document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemovingException); element.AppendChild (element2); AssertEquals (1, element.ChildNodes.Count); try { element.RemoveChild(element2); Fail ("Expected an exception to be thrown by the NodeRemoving event handler method EventNodeRemovingException()."); } catch (Exception) {} AssertEquals (1, element.ChildNodes.Count); } [Test] public void GetElementsByTagNameNoNameSpace () { string xml = @"XML FunJohn Doe 34.95Bear and the Dragon Tom Clancy6.95 Bourne IdentityRobert Ludlum 9.95 Bourne UltimatumRobert Ludlum 9.95"; MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml)); document = new XmlDocument (); document.Load (memoryStream); XmlNodeList bookList = document.GetElementsByTagName ("book"); AssertEquals ("GetElementsByTagName (string) returned incorrect count.", 4, bookList.Count); } [Test] public void GetElementsByTagNameUsingNameSpace () { StringBuilder xml = new StringBuilder (); xml.Append (" "); xml.Append ("XML Fun " ); xml.Append ("John Doe " ); xml.Append ("34.95 " ); xml.Append (" " ); xml.Append ("Bear and the Dragon " ); xml.Append ("Tom Clancy " ); xml.Append ("6.95 " ); xml.Append ("Bourne Identity " ); xml.Append ("Robert Ludlum " ); xml.Append ("9.95"); MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ())); document = new XmlDocument (); document.Load (memoryStream); XmlNodeList bookList = document.GetElementsByTagName ("book", "http://www.goo.com"); AssertEquals ("GetElementsByTagName (string, uri) returned incorrect count.", 2, bookList.Count); } [Test] public void GetElementsByTagNameNs2 () { document.LoadXml (@" text node "); // id='b' has different prefix. Should not caught by (name), // while should caught by (name, ns). XmlNodeList nl = document.GetElementsByTagName ("x:a"); AssertEquals (2, nl.Count); AssertEquals ("a", nl [0].Attributes ["id"].Value); AssertEquals ("c", nl [1].Attributes ["id"].Value); nl = document.GetElementsByTagName ("a", "urn:foo"); AssertEquals (3, nl.Count); AssertEquals ("a", nl [0].Attributes ["id"].Value); AssertEquals ("b", nl [1].Attributes ["id"].Value); AssertEquals ("c", nl [2].Attributes ["id"].Value); // name wildcard nl = document.GetElementsByTagName ("*"); AssertEquals (6, nl.Count); AssertEquals ("root", nl [0].Name); AssertEquals ("a", nl [1].Attributes ["id"].Value); AssertEquals ("b", nl [2].Attributes ["id"].Value); AssertEquals ("c", nl [3].Attributes ["id"].Value); AssertEquals ("d", nl [4].Attributes ["id"].Value); AssertEquals ("e", nl [5].Attributes ["id"].Value); // wildcard - local and ns nl = document.GetElementsByTagName ("*", "*"); AssertEquals (6, nl.Count); AssertEquals ("root", nl [0].Name); AssertEquals ("a", nl [1].Attributes ["id"].Value); AssertEquals ("b", nl [2].Attributes ["id"].Value); AssertEquals ("c", nl [3].Attributes ["id"].Value); AssertEquals ("d", nl [4].Attributes ["id"].Value); AssertEquals ("e", nl [5].Attributes ["id"].Value); // namespace wildcard - namespace nl = document.GetElementsByTagName ("*", "urn:foo"); AssertEquals (4, nl.Count); AssertEquals ("a", nl [0].Attributes ["id"].Value); AssertEquals ("b", nl [1].Attributes ["id"].Value); AssertEquals ("c", nl [2].Attributes ["id"].Value); AssertEquals ("e", nl [3].Attributes ["id"].Value); // namespace wildcard - local only. I dare say, such usage is not XML-ish! nl = document.GetElementsByTagName ("a", "*"); AssertEquals (3, nl.Count); AssertEquals ("a", nl [0].Attributes ["id"].Value); AssertEquals ("b", nl [1].Attributes ["id"].Value); AssertEquals ("c", nl [2].Attributes ["id"].Value); } [Test] public void Implementation () { AssertNotNull (new XmlDocument ().Implementation); } [Test] public void InnerAndOuterXml () { AssertEquals (String.Empty, document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); XmlDeclaration declaration = document.CreateXmlDeclaration ("1.0", null, null); document.AppendChild (declaration); AssertEquals ("", document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); XmlElement element = document.CreateElement ("foo"); document.AppendChild (element); AssertEquals ("", document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); XmlComment comment = document.CreateComment ("bar"); document.DocumentElement.AppendChild (comment); AssertEquals ("", document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); XmlText text = document.CreateTextNode ("baz"); document.DocumentElement.AppendChild (text); AssertEquals ("baz", document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); element = document.CreateElement ("quux"); element.SetAttribute ("quuux", "squonk"); document.DocumentElement.AppendChild (element); AssertEquals ("baz", document.InnerXml); AssertEquals (document.InnerXml, document.OuterXml); } [Test] public void LoadWithSystemIOStream () { string xml = @"XML FunJohn Doe 34.95Bear and the Dragon Tom Clancy6.95 Bourne IdentityRobert Ludlum 9.95 Bourne UltimatumRobert Ludlum 9.95"; MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml)); document = new XmlDocument (); document.Load (memoryStream); AssertEquals ("Not Loaded From IOStream", true, document.HasChildNodes); } [Test] public void LoadXmlReaderNamespacesFalse () { XmlTextReader xtr = new XmlTextReader ( "", XmlNodeType.Document, null); xtr.Namespaces = false; document.Load (xtr); // Don't complain about xmlns attribute with its namespaceURI == String.Empty. } [Test] public void LoadXmlCDATA () { document.LoadXml (""); Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.CDATA); AssertEquals ("bar", document.DocumentElement.FirstChild.Value); } [Test] public void LoadXMLComment() { // XmlTextReader needs to throw this exception // try { // document.LoadXml(""); // Fail("XmlException should have been thrown."); // } // catch (XmlException e) { // AssertEquals("Exception message doesn't match.", "The root element is missing.", e.Message); // } document.LoadXml (""); Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Comment); AssertEquals ("Comment", document.DocumentElement.FirstChild.Value); document.LoadXml (@""); AssertEquals ("Incorrect target.", "bar", ((XmlComment)document.FirstChild.FirstChild).Data); } [Test] public void LoadXmlElementSingle () { AssertNull (document.DocumentElement); document.LoadXml (""); AssertNotNull (document.DocumentElement); AssertSame (document.FirstChild, document.DocumentElement); AssertEquals (String.Empty, document.DocumentElement.Prefix); AssertEquals ("foo", document.DocumentElement.LocalName); AssertEquals (String.Empty, document.DocumentElement.NamespaceURI); AssertEquals ("foo", document.DocumentElement.Name); } [Test] public void LoadXmlElementWithAttributes () { AssertNull (document.DocumentElement); document.LoadXml (""); XmlElement documentElement = document.DocumentElement; AssertEquals ("baz", documentElement.GetAttribute ("bar")); AssertEquals ("quuux", documentElement.GetAttribute ("quux")); AssertEquals ("hello & world", documentElement.GetAttribute ("hoge")); AssertEquals ("hello & world", documentElement.Attributes ["hoge"].Value); AssertEquals (1, documentElement.GetAttributeNode ("hoge").ChildNodes.Count); } [Test] public void LoadXmlElementWithChildElement () { document.LoadXml (""); Assert (document.ChildNodes.Count == 1); Assert (document.FirstChild.ChildNodes.Count == 1); AssertEquals ("foo", document.DocumentElement.LocalName); AssertEquals ("bar", document.DocumentElement.FirstChild.LocalName); } [Test] public void LoadXmlElementWithTextNode () { document.LoadXml ("bar"); Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Text); AssertEquals ("bar", document.DocumentElement.FirstChild.Value); } [Test] public void LoadXmlExceptionClearsDocument () { document.LoadXml (""); Assert (document.FirstChild != null); try { document.LoadXml ("<123/>"); Fail ("An XmlException should have been thrown."); } catch (XmlException) {} Assert (document.FirstChild == null); } [Test] public void LoadXmlProcessingInstruction () { document.LoadXml (@""); AssertEquals ("Incorrect target.", "foo", ((XmlProcessingInstruction)document.FirstChild).Target); AssertEquals ("Incorrect data.", "bar='baaz' quux='quuux'", ((XmlProcessingInstruction)document.FirstChild).Data); } [Test] public void OuterXml () { string xml; xml = ""; document.LoadXml (xml); AssertEquals("XmlDocument with cdata OuterXml is incorrect.", xml, document.OuterXml); xml = ""; document.LoadXml (xml); AssertEquals("XmlDocument with comment OuterXml is incorrect.", xml, document.OuterXml); xml = ""; document.LoadXml (xml); AssertEquals("XmlDocument with processing instruction OuterXml is incorrect.", xml, document.OuterXml); } [Test] public void ParentNodes () { document.LoadXml (""); XmlNode node = document.FirstChild.FirstChild.FirstChild; AssertEquals ("Wrong child found.", "baz", node.LocalName); AssertEquals ("Wrong parent.", "bar", node.ParentNode.LocalName); AssertEquals ("Wrong parent.", "foo", node.ParentNode.ParentNode.LocalName); AssertEquals ("Wrong parent.", "#document", node.ParentNode.ParentNode.ParentNode.LocalName); AssertNull ("Expected parent to be null.", node.ParentNode.ParentNode.ParentNode.ParentNode); } [Test] public void RemovedElementNextSibling () { XmlNode node; XmlNode nextSibling; document.LoadXml (""); node = document.DocumentElement.FirstChild; document.DocumentElement.RemoveChild (node); nextSibling = node.NextSibling; AssertNull ("Expected removed node's next sibling to be null.", nextSibling); } // ImportNode [Test] public void ImportNode () { XmlNode n; string xlinkURI = "http://www.w3.org/1999/XLink"; string xml1 = "From here, simple text node."; document.LoadXml(xml1); XmlDocument newDoc = new XmlDocument(); newDoc.LoadXml(""); XmlElement bar = document.DocumentElement.FirstChild as XmlElement; // Attribute n = newDoc.ImportNode(bar.GetAttributeNode("href", xlinkURI), true); AssertEquals("#ImportNode.Attr.NS.LocalName", "href", n.LocalName); AssertEquals("#ImportNode.Attr.NS.NSURI", xlinkURI, n.NamespaceURI); AssertEquals("#ImportNode.Attr.NS.Value", "#foo", n.Value); // CDATA n = newDoc.ImportNode(bar.FirstChild.FirstChild, true); AssertEquals("#ImportNode.CDATA", "cdata section.\n\titem 1\n\titem 2\n", n.Value); // Element XmlElement e = newDoc.ImportNode(bar, true) as XmlElement; AssertEquals("#ImportNode.Element.Name", "bar", e.Name); AssertEquals("#ImportNode.Element.Attr", "#foo", e.GetAttribute("href", xlinkURI)); AssertEquals("#ImportNode.Element.deep", "baz", e.FirstChild.Name); // Entity Reference: // [2002/10/14] CreateEntityReference was not implemented. // document.LoadXml("]>&FOOENT;"); // n = newDoc.ImportNode(document.DocumentElement.FirstChild); // AssertEquals("#ImportNode.EntityReference", "FOOENT", n.Name); // AssertEquals("#ImportNode.EntityReference", "foo_", n.Value); // Processing Instruction document.LoadXml(""); XmlProcessingInstruction pi = (XmlProcessingInstruction)newDoc.ImportNode(document.DocumentElement.FirstChild, false); AssertEquals("#ImportNode.ProcessingInstruction.Name", "xml-stylesheet", pi.Name); AssertEquals("#ImportNode.ProcessingInstruction.Data", "href='foo.xsl'", pi.Data.Trim()); // Text document.LoadXml(xml1); n = newDoc.ImportNode((XmlText)bar.FirstChild.ChildNodes[1], true); AssertEquals("#ImportNode.Text", "From here, simple text node.", n.Value); // XmlDeclaration document.LoadXml(xml1); XmlDeclaration decl = (XmlDeclaration)newDoc.ImportNode(document.FirstChild, false); AssertEquals("#ImportNode.XmlDeclaration.Type", XmlNodeType.XmlDeclaration, decl.NodeType); AssertEquals("#ImportNode.XmlDeclaration.Encoding", "utf-8", decl.Encoding); } [Test] public void NameTable() { XmlDocument doc = new XmlDocument(); AssertNotNull(doc.NameTable); } [Test] public void SingleEmptyRootDocument() { XmlDocument doc = new XmlDocument(); doc.LoadXml(""); AssertNotNull(doc.DocumentElement); } [Test] public void DocumentWithDoctypeDecl () { XmlDocument doc = new XmlDocument (); // In fact it is invalid, but it doesn't fail with MS.NET 1.0. doc.LoadXml (""); AssertNotNull (doc.DocumentType); #if NetworkEnabled try { doc.LoadXml (""); } catch (XmlException) { Fail("#DoctypeDecl.System"); } try { doc.LoadXml (""); } catch (XmlException) { Fail ("#DoctypeDecl.Public"); } #endif // Should this be commented out? doc.LoadXml ("]>"); } [Test] public void CloneNode () { XmlDocument doc = new XmlDocument (); doc.LoadXml ("TEST Text"); XmlDocument doc2 = (XmlDocument)doc.CloneNode (false); AssertEquals ("ShallowCopy", 0, doc2.ChildNodes.Count); doc2 = (XmlDocument)doc.CloneNode (true); AssertEquals ("DeepCopy", "foo", doc2.DocumentElement.Name); } [Test] public void OuterXmlWithDefaultXmlns () { XmlDocument doc = new XmlDocument (); doc.LoadXml (""); AssertEquals ("", doc.OuterXml); } [Test] public void PreserveWhitespace () { string input = " "; XmlDocument dom = new XmlDocument (); XmlTextReader reader = new XmlTextReader (new StringReader (input)); dom.Load (reader); AssertEquals (XmlNodeType.Element, dom.FirstChild.NextSibling.NextSibling.NodeType); } [Test] public void PreserveWhitespace2 () { XmlDocument doc = new XmlDocument (); Assert (!doc.PreserveWhitespace); doc.PreserveWhitespace = true; XmlDocument d2 = doc.Clone () as XmlDocument; Assert (!d2.PreserveWhitespace); // i.e. not cloned d2.AppendChild (d2.CreateElement ("root")); d2.DocumentElement.AppendChild (d2.CreateWhitespace (" ")); StringWriter sw = new StringWriter (); d2.WriteTo (new XmlTextWriter (sw)); AssertEquals (" ", sw.ToString ()); } [Test] public void CreateAttribute () { XmlDocument dom = new XmlDocument (); // Check that null prefix and namespace are allowed and // equivalent to "" XmlAttribute attr = dom.CreateAttribute (null, "FOO", null); AssertEquals (attr.Prefix, ""); AssertEquals (attr.NamespaceURI, ""); } [Test] public void DocumentTypeNodes () { string entities = ""; string dtd = " " + entities + "]>"; string xml = dtd + "&foo;"; XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document, null); document.Load (xvr); AssertNotNull (document.DocumentType); AssertEquals (1, document.DocumentType.Entities.Count); XmlEntity foo = document.DocumentType.Entities.GetNamedItem ("foo") as XmlEntity; AssertNotNull (foo); AssertNotNull (document.DocumentType.Entities.GetNamedItem ("foo", "")); AssertEquals ("foo", foo.Name); AssertNull (foo.Value); AssertEquals ("foo-ent", foo.InnerText); } [Test] public void DTDEntityAttributeHandling () { string dtd = "]>"; string xml = dtd + "&foo;"; XmlValidatingReader xvr = new XmlValidatingReader (xml, XmlNodeType.Document,null); xvr.EntityHandling = EntityHandling.ExpandCharEntities; xvr.ValidationType = ValidationType.None; document.Load (xvr); // Don't include default attributes here. AssertEquals (xml, document.OuterXml); AssertEquals ("hoge-def", document.DocumentElement.GetAttribute ("hoge")); } // [Test] Comment out in the meantime. // public void LoadExternalUri () // { // // set any URL of well-formed XML. // document.Load ("http://www.go-mono.com/index.rss"); // } // [Test] comment out in the meantime. // public void LoadDocumentWithIgnoreSection () // { // // set any URL of well-formed XML. // document.Load ("xmlfiles/test.xml"); // } [Test] [ExpectedException (typeof (XmlException))] public void LoadThrowsUndeclaredEntity () { string ent1 = ""; string ent2 = "'>]>"; string dtd = "" + ent1 + ent2; string xml = dtd + "&ent3;&ent2;"; XmlTextReader xtr = new XmlTextReader (xml, XmlNodeType.Document, null); document.Load (xtr); xtr.Close (); } [Test] public void CreateEntityReferencesWithoutDTD () { document.RemoveAll (); document.AppendChild (document.CreateElement ("root")); document.DocumentElement.AppendChild (document.CreateEntityReference ("foo")); } [Test] public void LoadEntityReference () { string xml = "]>&ent;"; XmlTextReader xtr = new XmlTextReader (xml, XmlNodeType.Document, null); XmlDocument doc = new XmlDocument (); doc.Load (xtr); AssertEquals ("#text node", XmlNodeType.EntityReference, doc.DocumentElement.FirstChild.NodeType); AssertEquals ("#attribute", XmlNodeType.EntityReference, doc.DocumentElement.Attributes [0].ChildNodes [1].NodeType); } [Test] public void ReadNodeEmptyContent () { XmlTextReader xr = new XmlTextReader ("", XmlNodeType.Element, null); xr.Read (); Console.WriteLine (xr.NodeType); XmlNode n = document.ReadNode (xr); AssertNull (n); } [Test] public void ReadNodeWhitespace () { XmlTextReader xr = new XmlTextReader (" ", XmlNodeType.Element, null); xr.Read (); Console.WriteLine (xr.NodeType); document.PreserveWhitespace = false; // Note this line. XmlNode n = document.ReadNode (xr); AssertNotNull (n); AssertEquals (XmlNodeType.Whitespace, n.NodeType); } [Test] public void SavePreserveWhitespace () { string xml = " text\n"; XmlDocument doc = new XmlDocument (); doc.PreserveWhitespace = true; doc.LoadXml (xml); StringWriter sw = new StringWriter (); doc.Save (sw); AssertEquals ("" + xml, sw.ToString ()); doc.PreserveWhitespace = false; sw = new StringWriter (); doc.Save (sw); string NEL = Environment.NewLine; AssertEquals ("" + NEL + " text" + "\n", sw.ToString ()); } [Test] public void ReadNodeEntityReferenceFillsChildren () { string dtd = "]>"; string xml = dtd + "&ent;"; XmlValidatingReader reader = new XmlValidatingReader ( xml, XmlNodeType.Document, null); reader.EntityHandling = EntityHandling.ExpandCharEntities; reader.ValidationType = ValidationType.None; //skip the doctype delcaration reader.Read (); reader.Read (); XmlDocument doc = new XmlDocument (); doc.Load (reader); AssertEquals (1, doc.DocumentElement.FirstChild.ChildNodes.Count); } } }