Browse Source

2008-04-17 Atsushi Enomoto <[email protected]>

	* XmlAttributeCollection.cs : check attribute identity only if the
	  source node is in the document tree. Fixed bug #380720.

	* XmlElementTests.cs : added test for bug #380720.
	* XmlAttributeTests.cs : numbered some assertions.


svn path=/trunk/mcs/; revision=101019
Atsushi Eno 17 years ago
parent
commit
680bfdbdee

+ 5 - 0
mcs/class/System.XML/System.Xml/ChangeLog

@@ -1,3 +1,8 @@
+2008-04-17  Atsushi Enomoto  <[email protected]>
+
+	* XmlAttributeCollection.cs : check attribute identity only if the
+	  source node is in the document tree. Fixed bug #380720.
+
 2008-02-19  Atsushi Enomoto  <[email protected]>
 
 	* XmlParserContext.cs : .net does not populate XmlNamespaceManager

+ 6 - 3
mcs/class/System.XML/System.Xml/XmlAttributeCollection.cs

@@ -334,9 +334,12 @@ namespace System.Xml
 
 			// adding new identical attribute, but 
 			// MS.NET is pity for ID support, so I'm wondering how to correct it...
-			if (ownerDocument.GetIdenticalAttribute (node.Value) != null)
-				throw new XmlException (String.Format (
-					"ID value {0} already exists in this document.", node.Value));
+			if (ownerElement.IsRooted) {
+				XmlAttribute dup = ownerDocument.GetIdenticalAttribute (node.Value);
+				if (dup != null && dup.OwnerElement != null && dup.OwnerElement.IsRooted)
+					throw new XmlException (String.Format (
+						"ID value {0} already exists in this document.", node.Value));
+			}
 			ownerDocument.AddIdenticalAttribute (node);
 		}
 

+ 5 - 0
mcs/class/System.XML/Test/System.Xml/ChangeLog

@@ -1,3 +1,8 @@
+2008-04-17  Atsushi Enomoto  <[email protected]>
+
+	* XmlElementTests.cs : added test for bug #380720.
+	* XmlAttributeTests.cs : numbered some assertions.
+
 2008-04-02  Atsushi Enomoto  <[email protected]>
 
 	* XsdValidatingReaderTests.cs : added test for bug #376395.

+ 13 - 13
mcs/class/System.XML/Test/System.Xml/XmlAttributeTests.cs

@@ -252,36 +252,36 @@ namespace MonoTests.System.Xml
 			string xml = dtd + "<root><c foo='id1' bar='1' /><c foo='id2' bar='2'/></root>";
 			XmlValidatingReader vr = new XmlValidatingReader (xml, XmlNodeType.Document, null);
 			doc.Load (vr);
-			Assert.IsNotNull (doc.GetElementById ("id1"));
-			Assert.IsNotNull (doc.GetElementById ("id2"));
+			Assert.IsNotNull (doc.GetElementById ("id1"), "#1");
+			Assert.IsNotNull (doc.GetElementById ("id2"), "#2");
 			// MS.NET BUG: Later I try to append it to another element, but
 			// it should raise InvalidOperationException.
 			// (and if MS.NET conform to DOM 1.0, it should be XmlException.)
 //			XmlAttribute attr = doc.DocumentElement.FirstChild.Attributes [0];
 			XmlAttribute attr = doc.DocumentElement.FirstChild.Attributes.RemoveAt (0);
-			Assert.AreEqual ("id1", attr.Value);
+			Assert.AreEqual ("id1", attr.Value, "#3");
 
 			doc.DocumentElement.LastChild.Attributes.SetNamedItem (attr);
-			Assert.IsNotNull (doc.GetElementById ("id1"));
+			Assert.IsNotNull (doc.GetElementById ("id1"), "#4");
 			XmlElement elem2 = doc.GetElementById ("id2");
 			// MS.NET BUG: it doesn't remove replaced attribute with SetNamedItem!
-//			AssertNull (elem2);
-//			AssertEquals ("2", elem2.GetAttribute ("bar"));
+//			AssertNull (elem2, "#5");
+//			AssertEquals ("2", elem2.GetAttribute ("bar"), "#6");
 //			elem2.RemoveAttribute ("foo");
-//			AssertEquals (string.Empty, elem2.GetAttribute ("foo"));
+//			AssertEquals (string.Empty, elem2.GetAttribute ("foo"), "#7");
 
 			// MS.NET BUG: elem should be the element which has the attribute bar='1'!
 			XmlElement elem = doc.GetElementById ("id1");
-//			AssertEquals ("2", elem.GetAttribute ("bar"));
+//			AssertEquals ("2", elem.GetAttribute ("bar"), "#8");
 
 			// Here, required attribute foo is no more required,
 			XmlElement elemNew = doc.CreateElement ("c");
 			doc.DocumentElement.AppendChild (elemNew);
 			// but once attribute is set, document recognizes this ID.
 			elemNew.SetAttribute ("foo", "id3");
-			Assert.IsNotNull (doc.GetElementById ("id3"));
+			Assert.IsNotNull (doc.GetElementById ("id3"), "#9");
 			elemNew.RemoveAttribute ("foo");
-			Assert.IsNull (doc.GetElementById ("id3"));
+			Assert.IsNull (doc.GetElementById ("id3"), "#10");
 
 			// MS.NET BUG: multiple IDs are allowed.
 			// In such case GetElementById fails.
@@ -293,9 +293,9 @@ namespace MonoTests.System.Xml
 
 			// Finally...
 			doc.RemoveAll ();
-			Assert.IsNull (doc.GetElementById ("id1"));
-			Assert.IsNull (doc.GetElementById ("id2"));
-			Assert.IsNull (doc.GetElementById ("id3"));
+			Assert.IsNull (doc.GetElementById ("id1"), "#11");
+			Assert.IsNull (doc.GetElementById ("id2"), "#12");
+			Assert.IsNull (doc.GetElementById ("id3"), "#13");
 		}
 
 		int removeAllStep;

+ 15 - 0
mcs/class/System.XML/Test/System.Xml/XmlElementTests.cs

@@ -611,6 +611,21 @@ namespace MonoTests.System.Xml
 			new MyXmlElement ("foo", "urn:foo", new XmlDocument ());
 		}
 
+		[Test] // bug #380720
+		public void SetAttributeWithIdentity ()
+		{
+			XmlDocument doc = new XmlDocument ();
+			doc.LoadXml (@"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' []>
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head></head>
+<body><div id='xxx'>XXX</div><div id='yyy'>YYY</div></body>
+</html>");
+			XmlElement xxx = (XmlElement) doc.GetElementsByTagName ("div") [0];
+			XmlElement yyy = (XmlElement) doc.GetElementsByTagName ("div") [1];
+			yyy.ParentNode.RemoveChild (yyy);
+			yyy.SetAttribute ("id", "xxx");
+		}
+
 		class MyXmlElement : XmlElement
 		{
 			public MyXmlElement (string localName, string ns, XmlDocument doc)