Fix bug #12035 - xsi:nil='true' was ignored in some scenario.
authorAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Wed, 7 Aug 2013 16:00:10 +0000 (01:00 +0900)
committerAtsushi Eno <atsushieno@veritas-vos-liberabit.com>
Wed, 7 Aug 2013 16:00:10 +0000 (01:00 +0900)
"some scenario" I mean:

- There is a sequence with more than one elements in xsd,
- The second element is nillable and its type has content elements, and
- The corresponding XML element specifies xsi:nil='true'

Then it resulted in a validation error as if it were missing the required
content.

mcs/class/System.XML/Mono.Xml.Schema/XsdValidatingReader.cs
mcs/class/System.XML/System.Xml.Schema/XmlSchemaValidator.cs
mcs/class/System.XML/Test/System.Xml.Schema/XmlSchemaValidatorTests.cs

index 7f19ce58d3d06ab83ab969b2642b2647bfb3f6f6..f6b56c6b3c6e6d7ed71f16884b69f40bc912ff21 100644 (file)
@@ -473,7 +473,7 @@ namespace Mono.Xml.Schema
 
                private void ValidateEndElementParticle ()
                {
-                       if (Context.State != null) {
+                       if (xsiNilDepth < 0 && Context.State != null) {
                                if (!Context.EvaluateEndElement ()) {
                                        HandleError ("Invalid end element: " + reader.Name);
                                }
index 92274b2e15758ccd09a72d3b692b9aebfa4da923..286963d3056ebe5029a59002baa6fa75cccd6852 100644 (file)
@@ -539,10 +539,10 @@ namespace System.Xml.Schema
 
                                if (skipValidationDepth < 0 || depth <= skipValidationDepth)
                                        AssessCloseStartElementSchemaValidity (schemaInfo);
-                               depth++;
                        } finally {
                                current_info = null;
                                occuredAtts.Clear ();
+                               depth++;
                        }
                }
 
@@ -976,7 +976,7 @@ namespace System.Xml.Schema
 
                private void ValidateEndElementParticle ()
                {
-                       if (Context.State != null) {
+                       if (xsiNilDepth < 0 && Context.State != null) {
                                if (!Context.EvaluateEndElement ()) {
                                        HandleError ("Invalid end element. There are still required content items.");
                                }
@@ -1588,7 +1588,8 @@ namespace System.Xml.Schema
                        if (value == "true") {
                                if (element.ValidatedFixedValue != null)
                                        HandleError ("Schema instance nil was specified, where the element declaration for " + element.QualifiedName + "has fixed value constraints.");
-                               xsiNilDepth = depth;
+                               if (xsiNilDepth < 0)
+                                       xsiNilDepth = depth;
                                if (info != null)
                                        info.IsNil = true;
                        }
index bf258f6cc17b453e60aaafdb474fb2a07ef26fe6..6f7ec34a5dd6e730d5bfbc8983980bfc853781c3 100644 (file)
@@ -397,6 +397,50 @@ namespace MonoTests.System.Xml
                                i++;
                        Assert.AreEqual (2, i, "#2");
                }
+               
+               [Test]
+               public void Bug12035 ()
+               {
+                       string xml = @"<UserSettings
+  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+  xmlns:xsd='http://www.w3.org/2001/XMLSchema'
+  xmlns='http://schema/test'><Enabled>false</Enabled><Time xsi:nil='true' /></UserSettings>";
+                       string xsd = @"<?xml version='1.0' encoding='utf-8'?>
+<xs:schema
+  targetNamespace='http://schema/test'
+  xmlns='http://schema/test'
+  xmlns:xs='http://www.w3.org/2001/XMLSchema'
+  elementFormDefault='qualified'>
+  <xs:element name='UserSettings'>
+    <xs:complexType>
+      <xs:sequence>
+        <xs:element name='Enabled' type='xs:boolean' />
+        <xs:element name='Time' type='CoarseTime' nillable='true' />
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+
+  <xs:complexType name='CoarseTime'>
+    <xs:sequence>
+      <xs:element name='Hours' type='xs:int' />
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>";
+                       var schema = XmlSchema.Read (new StringReader (xsd), null);
+                       var schemaSet = new XmlSchemaSet ();
+                       schemaSet.Add (schema);
+                       var xmlReaderSettings = new XmlReaderSettings { ValidationType = ValidationType.Schema };
+                       xmlReaderSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
+                       xmlReaderSettings.Schemas.Add (schemaSet);
+                       
+                       using (var configStream = new StringReader (xml)) {
+                               using (var validatingReader = XmlReader.Create (configStream, xmlReaderSettings)) {
+                                       // Read the XML, throwing an exception if a validation error occurs
+                                       while (validatingReader.Read()) {
+                                       }
+                               }
+                       }
+               }
        }
 }