// // XmlSchemaValidatorTests.cs // // Author: // Atsushi Enomoto <atsushi@ximian.com> // // (C) 2008 Novell Inc. // using System; using System.Collections; using System.IO; using System.Xml; using System.Xml.Schema; using NUnit.Framework; namespace MonoTests.System.Xml { [TestFixture] public class XmlSchemaValidatorTests { void Validate (string xml, string xsd) { XmlSchema schema = XmlSchema.Read (new StringReader (xsd), null); XmlReaderSettings settings = new XmlReaderSettings (); settings.ValidationType = ValidationType.Schema; settings.Schemas.Add (schema); XmlReader reader = XmlReader.Create (new StringReader (xml), settings); while (reader.Read ()) ; } [Test] public void XsdAnyToSkipAttributeValidation () { // bug #358408 XmlSchemaSet schemas = new XmlSchemaSet (); schemas.Add (null, "Test/XmlFiles/xsd/358408.xsd"); XmlSchemaValidator v = new XmlSchemaValidator ( new NameTable (), schemas, new XmlNamespaceManager (new NameTable ()), XmlSchemaValidationFlags.ProcessIdentityConstraints); v.Initialize (); v.ValidateWhitespace (" "); XmlSchemaInfo info = new XmlSchemaInfo (); ArrayList list = new ArrayList (); v.ValidateElement ("configuration", "", info, null, null, null, null); v.GetUnspecifiedDefaultAttributes (list); v.ValidateEndOfAttributes (info); v.ValidateWhitespace (" "); v.ValidateElement ("host", "", info, null, null, null, null); v.ValidateAttribute ("auto-start", "", "true", info); list.Clear (); v.GetUnspecifiedDefaultAttributes (list); v.ValidateEndOfAttributes (info); v.ValidateEndElement (null);//info); v.ValidateWhitespace (" "); v.ValidateElement ("service-managers", "", info, null, null, null, null); list.Clear (); v.GetUnspecifiedDefaultAttributes (list); v.ValidateEndOfAttributes (info); v.ValidateWhitespace (" "); v.ValidateElement ("service-manager", "", info, null, null, null, null); list.Clear (); v.GetUnspecifiedDefaultAttributes (list); v.ValidateEndOfAttributes (info); v.ValidateWhitespace (" "); v.ValidateElement ("foo", "", info, null, null, null, null); v.ValidateAttribute ("bar", "", "", info); } [Test] public void SkipInvolved () // bug #422581 { XmlReader schemaReader = XmlReader.Create ("Test/XmlFiles/xsd/422581.xsd"); XmlSchema schema = XmlSchema.Read (schemaReader, null); XmlReaderSettings settings = new XmlReaderSettings (); settings.ValidationType = ValidationType.Schema; settings.Schemas.Add (schema); XmlReader reader = XmlReader.Create ("Test/XmlFiles/xsd/422581.xml", settings); while (reader.Read ()); } [Test] public void Bug433774 () { string xsd = @"<xs:schema targetNamespace='urn:foo' xmlns='urn:foo' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='Root'> <xs:complexType> <xs:sequence></xs:sequence> <xs:attribute name='version' type='xs:string' fixed='3' /> </xs:complexType> </xs:element> </xs:schema>"; XmlDocument doc = new XmlDocument (); doc.LoadXml ("<Root version='3' xmlns='urn:foo'/>"); XmlSchemaSet schemaSet = new XmlSchemaSet(); schemaSet.Add (XmlSchema.Read (XmlReader.Create (new StringReader (xsd)), null)); doc.Schemas = schemaSet; XmlNode root = doc.DocumentElement; doc.Validate (null, root); } [Test] [ExpectedException (typeof (XmlSchemaValidationException))] public void Bug435206 () { string xsd = @"<xs:schema attributeFormDefault='unqualified' elementFormDefault='qualified' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='myDoc'> <xs:complexType> <xs:attribute name='foo' type='xs:unsignedLong' use='required' /> <xs:attribute name='bar' type='xs:dateTime' use='required' /> </xs:complexType> </xs:element> </xs:schema>"; string xml = @"<myDoc foo='12' bar='January 1st 1900'/>"; Validate (xml, xsd); } [Test] public void Bug469713 () { string xsd = @"<xs:schema elementFormDefault='qualified' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='Message'> <xs:complexType> <xs:all> <xs:element name='MyDateTime' nillable='true' type='xs:dateTime' /> </xs:all> </xs:complexType> </xs:element> </xs:schema>"; string xml = @"<Message xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='test.xsd'> <MyDateTime xsi:nil='true'></MyDateTime> </Message>"; Validate (xml, xsd); } [Test] public void Bug496192_496205 () { using (var xmlr = new StreamReader ("Test/XmlFiles/496192.xml")) using (var xsdr = new StreamReader ("Test/XmlFiles/496192.xsd")) Validate (xmlr.ReadToEnd (), xsdr.ReadToEnd ()); } [Test] public void Bug501666 () { string xsd = @" <xs:schema id='Settings' targetNamespace='foo' xmlns='foo' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='Settings' type='Settings'/> <xs:complexType name='Settings'> <xs:attribute name='port' type='PortNumber' use='required'/> </xs:complexType> <xs:simpleType name='PortNumber'> <xs:restriction base='xs:positiveInteger'> <xs:minInclusive value='1'/> <xs:maxInclusive value='65535'/> </xs:restriction> </xs:simpleType> </xs:schema>"; string xml = @"<Settings port='1337' xmlns='foo'/>"; XmlDocument doc = new XmlDocument (); doc.LoadXml (xml); doc.Schemas.Add (XmlSchema.Read (XmlReader.Create (new StringReader (xsd)), null)); doc.Validate (null); } public void Bug502251 () { string xsd = @" <xs:schema id='foo' targetNamespace='foo' elementFormDefault='qualified' xmlns='foo' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:group name='LayoutElementTypes'> <xs:choice> <xs:element name='Rows' type='Rows' /> <xs:element name='Conditional' type='Conditional' /> </xs:choice> </xs:group> <xs:complexType name='Element' abstract='true'> <xs:attribute name='id' type='xs:ID' use='optional'/> </xs:complexType> <xs:complexType name='SingleChildElement' abstract='true'> <xs:complexContent> <xs:extension base='Element'> <xs:group ref='LayoutElementTypes' minOccurs='1' maxOccurs='1' /> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name='Rows'> <xs:complexContent> <xs:extension base='Element'> <xs:sequence minOccurs='1' maxOccurs='unbounded'> <xs:element name='Row' type='Row' /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name='Row'> <xs:complexContent> <xs:extension base='SingleChildElement'> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name='Conditional'> <xs:complexContent> <xs:extension base='Element'> </xs:extension> </xs:complexContent> </xs:complexType> <xs:complexType name='Layout'> <xs:complexContent> <xs:extension base='SingleChildElement'> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name='Layout' type='Layout' /> </xs:schema>"; XmlDocument doc = new XmlDocument (); doc.LoadXml (@"<Layout xmlns='foo'> <Rows> <Row><Conditional/></Row> </Rows> </Layout>"); XmlSchema schema = XmlSchema.Read (XmlReader.Create (new StringReader (xsd)), null); doc.Schemas.Add (schema); doc.Validate (null); } [Test] public void Bug557452 () { string xsd = @" <xs:schema id='Settings' targetNamespace='foo' xmlns='foo' xmlns:xs='http://www.w3.org/2001/XMLSchema'> <xs:element name='Settings' type='Settings'/> <xs:complexType name='Settings'> <xs:attribute name='port' type='PortNumber' use='required'/> </xs:complexType> <xs:simpleType name='PortNumber'> <xs:restriction base='xs:decimal'> <xs:minInclusive value='1'/> <xs:maxInclusive value='65535'/> </xs:restriction> </xs:simpleType> </xs:schema>"; string xml = @"<Settings port='1337' xmlns='foo'/>"; XmlDocument doc = new XmlDocument (); doc.LoadXml (xml); doc.Schemas.Add (XmlSchema.Read (XmlReader.Create (new StringReader (xsd)), null)); doc.Validate (null); } [Test] public void Bug584664 () { Validate (File.ReadAllText ("Test/XmlFiles/xsd/584664a.xml"), File.ReadAllText ("Test/XmlFiles/xsd/584664a.xsd")); Validate (File.ReadAllText ("Test/XmlFiles/xsd/584664b.xml"), File.ReadAllText ("Test/XmlFiles/xsd/584664b.xsd")); } [Test] public void MultipleMissingIds () { var schema = XmlSchema.Read (new StringReader (@"<?xml version=""1.0"" encoding=""utf-8""?> <xs:schema targetNamespace=""urn:multiple-ids"" elementFormDefault=""qualified"" xmlns=""urn:multiple-ids"" xmlns:xs=""http://www.w3.org/2001/XMLSchema""> <xs:element name=""root""> <xs:complexType> <xs:sequence minOccurs=""0"" maxOccurs=""unbounded""> <xs:element name=""item""> <xs:complexType> <xs:attribute name=""id"" type=""xs:ID"" /> <xs:attribute name=""parent"" type=""xs:IDREF"" /> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>"), null); var xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <root xmlns=""urn:multiple-ids""> <item id=""id2"" parent=""id1"" /> <item id=""id3"" parent=""id1"" /> <item id=""id1"" parent=""id1"" /> </root>"; var document = new XmlDocument (); document.LoadXml (xml); document.Schemas = new XmlSchemaSet (); document.Schemas.Add (schema); document.Validate (null); } [Test] public void FacetsOnBaseSimpleContentRestriction () { XmlReaderSettings settings = new XmlReaderSettings (); settings.Schemas.Add (null, "Test/XmlFiles/595947.xsd"); settings.ValidationType = ValidationType.Schema; settings.Schemas.Compile (); Validate ("TEST 1.1", 1, "0123456789", "0123456789", settings, false); Validate ("TEST 1.2", 1, "0123456789***", "0123456789", settings, true); Validate ("TEST 1.3", 1, "0123456789", "0123456789***", settings, true); Validate ("TEST 2.1", 2, "0123456789", "0123456789", settings, false); Validate ("TEST 2.2", 2, "0123456789***", "0123456789", settings, true); Validate ("TEST 2.3", 2, "0123456789", "0123456789***", settings, true); Validate ("TEST 3.1", 3, "0123456789", "0123456789", settings, false); Validate ("TEST 3.2", 3, "0123456789***", "0123456789", settings, true); Validate ("TEST 3.3", 3, "0123456789", "0123456789***", settings, true); } void Validate (string testName, int testNumber, string idValue, string elementValue, XmlReaderSettings settings, bool shouldFail) { string content = string.Format ("<MyTest{0} Id=\"{1}\">{2}</MyTest{0}>", testNumber, idValue, elementValue); try { XmlReader reader = XmlReader.Create (new StringReader (content), settings); XmlDocument document = new XmlDocument (); document.Load (reader); document.Validate (null); } catch (Exception e) { if (!shouldFail) throw; return; } if (shouldFail) Assert.Fail (testName + " should fail"); } [Test] public void Bug676993 () { Validate (File.ReadAllText ("Test/XmlFiles/676993.xml"), File.ReadAllText ("Test/XmlFiles/676993.xsd")); } [Test] public void Bug10245 () { string xsd = @" <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' targetNamespace='urn:foo'> <xs:element name='root'> <xs:complexType> <xs:attribute name='d' default='v' use='optional' /> </xs:complexType> </xs:element> </xs:schema>"; string xml = "<root xmlns='urn:foo' />"; var xrs = new XmlReaderSettings () { ValidationType = ValidationType.Schema }; xrs.Schemas.Add (XmlSchema.Read (new StringReader (xsd), null)); var xr = XmlReader.Create (new StringReader (xml), xrs); xr.Read (); bool more; Assert.AreEqual (2, xr.AttributeCount, "#1"); int i = 0; for (more = xr.MoveToFirstAttribute (); more; more = xr.MoveToNextAttribute ()) 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()) { } } } } [Test] public void IgnoresInvalidBaseUri () { var source = new StringReader (@"<?xml version='1.0' encoding='utf-8'?><Test></Test>"); var readerSettings = new XmlReaderSettings { ValidationType = ValidationType.Schema }; var reader = XmlReader.Create (source, readerSettings, "invalidBaseUri"); Assert.IsNotNull (reader); } } }