59abd6b8253a0bd8638e407dda73bf479d31a8ea
[mono.git] / mcs / class / System.XML / Test / System.Xml.Schema / XmlSchemaTests.cs
1 //
2 // System.Xml.XmlSchemaTests.cs
3 //
4 // Author:
5 //   Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // (C) 2002 Atsushi Enomoto
8 //
9
10 using System;
11 using System.IO;
12 using System.Net;
13 using System.Xml;
14 using System.Xml.Schema;
15 using System.Xml.Serialization;
16 using NUnit.Framework;
17
18 namespace MonoTests.System.Xml
19 {       
20         [TestFixture]
21         public class XmlSchemaTests : XmlSchemaAssertion
22         {
23                 [Test]
24                 public void TestRead ()
25                 {
26                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/1.xsd");
27                         AssertEquals (6, schema.Items.Count);
28
29                         bool fooValidated = false;
30                         bool barValidated = false;
31                         string ns = "urn:bar";
32
33                         foreach (XmlSchemaObject obj in schema.Items) {
34                                 XmlSchemaElement element = obj as XmlSchemaElement;
35                                 if (element == null)
36                                         continue;
37                                 if (element.Name == "Foo") {
38                                         AssertElement (element, "Foo", 
39                                                 XmlQualifiedName.Empty, null,
40                                                 QName ("string", XmlSchema.Namespace), null);
41                                         fooValidated = true;
42                                 }
43                                 if (element.Name == "Bar") {
44                                         AssertElement (element, "Bar",
45                                                 XmlQualifiedName.Empty, null, QName ("FugaType", ns), null);
46                                         barValidated = true;
47                                 }
48                         }
49                         Assert (fooValidated);
50                         Assert (barValidated);
51                 }
52
53                 [Test]
54                 public void TestReadFlags ()
55                 {
56                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/2.xsd");
57                         schema.Compile (null);
58                         XmlSchemaElement el = schema.Items [0] as XmlSchemaElement;
59                         AssertNotNull (el);
60                         AssertEquals (XmlSchemaDerivationMethod.Extension, el.Block);
61
62                         el = schema.Items [1] as XmlSchemaElement;
63                         AssertNotNull (el);
64                         AssertEquals (XmlSchemaDerivationMethod.Extension |
65                                 XmlSchemaDerivationMethod.Restriction, el.Block);
66                 }
67
68                 [Test]
69                 public void TestWriteFlags ()
70                 {
71                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/2.xsd");
72                         StringWriter sw = new StringWriter ();
73                         XmlTextWriter xtw = new XmlTextWriter (sw);
74                         schema.Write (xtw);
75                 }
76
77                 [Test]
78                 public void TestCompile ()
79                 {
80                         XmlQualifiedName qname;
81                         XmlSchemaComplexContentExtension xccx;
82                         XmlSchemaComplexType cType;
83                         XmlSchemaSequence seq;
84
85                         XmlSchema schema = GetSchema ("Test/XmlFiles/xsd/1.xsd");
86 //                      Assert (!schema.IsCompiled);
87                         schema.Compile (null);
88                         Assert (schema.IsCompiled);
89                         string ns = "urn:bar";
90
91                         XmlSchemaElement foo = (XmlSchemaElement) schema.Elements [QName ("Foo", ns)];
92                         AssertNotNull (foo);
93                         XmlSchemaDatatype stringDatatype = foo.ElementType as XmlSchemaDatatype;
94                         AssertNotNull (stringDatatype);
95
96                         // HogeType
97                         qname = QName ("HogeType", ns);
98                         cType = schema.SchemaTypes [qname] as XmlSchemaComplexType;
99                         AssertNotNull (cType);
100                         AssertNull (cType.ContentModel);
101                         AssertCompiledComplexType (cType, qname, 0, 0,
102                                 false, null, true, XmlSchemaContentType.ElementOnly);
103                         seq = cType.ContentTypeParticle as XmlSchemaSequence;
104                         AssertNotNull (seq);
105                         AssertEquals (2, seq.Items.Count);
106                         XmlSchemaElement refFoo = seq.Items [0] as XmlSchemaElement;
107                         AssertCompiledElement (refFoo, QName ("Foo", ns), stringDatatype);
108
109                         // FugaType
110                         qname = QName ("FugaType", ns);
111                         cType = schema.SchemaTypes [qname] as XmlSchemaComplexType;
112                         AssertNotNull (cType);
113                         xccx = cType.ContentModel.Content as XmlSchemaComplexContentExtension;
114                         AssertCompiledComplexContentExtension (
115                                 xccx, 0, false, QName ("HogeType", ns));
116
117                         AssertCompiledComplexType (cType, qname, 0, 0,
118                                 false, typeof (XmlSchemaComplexContent),
119                                 true, XmlSchemaContentType.ElementOnly);
120                         AssertNotNull (cType.BaseSchemaType);
121
122                         seq = xccx.Particle as XmlSchemaSequence;
123                         AssertNotNull (seq);
124                         AssertEquals (1, seq.Items.Count);
125                         XmlSchemaElement refBaz = seq.Items [0] as XmlSchemaElement;
126                         AssertNotNull (refBaz);
127                         AssertCompiledElement (refBaz, QName ("Baz", ""), stringDatatype);
128
129                         qname = QName ("Bar", ns);
130                         XmlSchemaElement element = schema.Elements [qname] as XmlSchemaElement;
131                         AssertCompiledElement (element, qname, cType);
132                 }
133
134                 [Test]
135                 [ExpectedException (typeof (XmlSchemaException))]
136                 public void TestCompile_ZeroLength_TargetNamespace ()
137                 {
138                         XmlSchema schema = new XmlSchema ();
139                         schema.TargetNamespace = string.Empty;
140                         Assert (!schema.IsCompiled);
141
142                         // MS.NET 1.x: The Namespace '' is an invalid URI.
143                         // MS.NET 2.0: The targetNamespace attribute cannot have empty string as its value.
144                         schema.Compile (null);
145                 }
146
147                 [Test]
148                 [ExpectedException (typeof (XmlSchemaException))]
149                 public void TestCompileNonSchema ()
150                 {
151                         XmlTextReader xtr = new XmlTextReader ("<root/>", XmlNodeType.Document, null);
152                         XmlSchema schema = XmlSchema.Read (xtr, null);
153                         xtr.Close ();
154                 }
155
156                 [Test]
157                 public void TestSimpleImport ()
158                 {
159                         XmlSchema schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/3.xsd"), null);
160                         AssertEquals ("urn:foo", schema.TargetNamespace);
161                         XmlSchemaImport import = schema.Includes [0] as XmlSchemaImport;
162                         AssertNotNull (import);
163
164                         schema.Compile (null);
165                         AssertEquals (4, schema.Elements.Count);
166                         AssertNotNull (schema.Elements [QName ("Foo", "urn:foo")]);
167                         AssertNotNull (schema.Elements [QName ("Bar", "urn:foo")]);
168                         AssertNotNull (schema.Elements [QName ("Foo", "urn:bar")]);
169                         AssertNotNull (schema.Elements [QName ("Bar", "urn:bar")]);
170                         
171                 }
172
173                 [Test]
174                 public void TestSimpleMutualImport ()
175                 {
176                         XmlReader r = new XmlTextReader ("Test/XmlFiles/xsd/inter-inc-1.xsd");
177                         try {
178                                 XmlSchema.Read (r, null).Compile (null);
179                         } finally {
180                                 r.Close ();
181                         }
182                 }
183
184                 [Test]
185                 public void TestQualification ()
186                 {
187                         XmlSchema schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/5.xsd"), null);
188                         schema.Compile (null);
189                         XmlSchemaElement el = schema.Elements [QName ("Foo", "urn:bar")] as XmlSchemaElement;
190                         AssertNotNull (el);
191                         XmlSchemaComplexType ct = el.ElementType as XmlSchemaComplexType;
192                         XmlSchemaSequence seq = ct.ContentTypeParticle as XmlSchemaSequence;
193                         XmlSchemaElement elp = seq.Items [0] as XmlSchemaElement;
194                         AssertEquals (QName ("Bar", ""), elp.QualifiedName);
195
196                         schema = XmlSchema.Read (new XmlTextReader ("Test/XmlFiles/xsd/6.xsd"), null);
197                         schema.Compile (null);
198                         el = schema.Elements [QName ("Foo", "urn:bar")] as XmlSchemaElement;
199                         AssertNotNull (el);
200                         ct = el.ElementType as XmlSchemaComplexType;
201                         seq = ct.ContentTypeParticle as XmlSchemaSequence;
202                         elp = seq.Items [0] as XmlSchemaElement;
203                         AssertEquals (QName ("Bar", "urn:bar"), elp.QualifiedName);
204                 }
205
206                 [Test]
207                 public void TestWriteNamespaces ()
208                 {
209                         XmlDocument doc = new XmlDocument ();
210                         XmlSchema xs;
211                         StringWriter sw;
212                         XmlTextWriter xw;
213
214                         // empty
215                         xs = new XmlSchema ();
216                         sw = new StringWriter ();
217                         xw = new XmlTextWriter (sw);
218                         xs.Write (xw);
219                         doc.LoadXml (sw.ToString ());
220                         AssertEquals ("#1", "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
221
222                         // TargetNamespace
223                         xs = new XmlSchema ();
224                         sw = new StringWriter ();
225                         xw = new XmlTextWriter (sw);
226                         xs.TargetNamespace = "urn:foo";
227                         xs.Write (xw);
228                         doc.LoadXml (sw.ToString ());
229                         AssertEquals ("#2", "<xs:schema xmlns:tns=\"urn:foo\" targetNamespace=\"urn:foo\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
230
231                         // Zero-length TargetNamespace
232                         xs = new XmlSchema ();
233                         sw = new StringWriter ();
234                         xw = new XmlTextWriter (sw);
235                         xs.TargetNamespace = string.Empty;
236                         xs.Write (xw);
237                         doc.LoadXml (sw.ToString ());
238                         AssertEquals ("#2b", "<xs:schema targetNamespace=\"\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
239
240                         // XmlSerializerNamespaces
241                         xs = new XmlSchema ();
242                         sw = new StringWriter ();
243                         xw = new XmlTextWriter (sw);
244                         xs.Namespaces.Add ("hoge", "urn:hoge");
245                         xs.Write (xw);
246                         doc.LoadXml (sw.ToString ());
247                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
248                         // AssertEquals ("#3", "<schema xmlns:hoge=\"urn:hoge\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
249
250                         // TargetNamespace + XmlSerializerNamespaces
251                         xs = new XmlSchema ();
252                         sw = new StringWriter ();
253                         xw = new XmlTextWriter (sw);
254                         xs.TargetNamespace = "urn:foo";
255                         xs.Namespaces.Add ("hoge", "urn:hoge");
256                         xs.Write (xw);
257                         doc.LoadXml (sw.ToString ());
258                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
259                         // AssertEquals ("#4", "<schema xmlns:hoge=\"urn:hoge\" targetNamespace=\"urn:foo\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
260
261                         // Add XmlSchema.Namespace to XmlSerializerNamespaces
262                         xs = new XmlSchema ();
263                         sw = new StringWriter ();
264                         xw = new XmlTextWriter (sw);
265                         xs.Namespaces.Add ("a", XmlSchema.Namespace);
266                         xs.Write (xw);
267                         doc.LoadXml (sw.ToString ());
268                         AssertEquals ("#5", "<a:schema xmlns:a=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
269
270                         // UnhandledAttributes + XmlSerializerNamespaces
271                         xs = new XmlSchema ();
272                         sw = new StringWriter ();
273                         xw = new XmlTextWriter (sw);
274                         XmlAttribute attr = doc.CreateAttribute ("hoge");
275                         xs.UnhandledAttributes = new XmlAttribute [] {attr};
276                         xs.Namespaces.Add ("hoge", "urn:hoge");
277                         xs.Write (xw);
278                         doc.LoadXml (sw.ToString ());
279                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
280                         // AssertEquals ("#6", "<schema xmlns:hoge=\"urn:hoge\" hoge=\"\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
281
282                         // Adding xmlns to UnhandledAttributes -> no output
283                         xs = new XmlSchema ();
284                         sw = new StringWriter ();
285                         xw = new XmlTextWriter (sw);
286                         attr = doc.CreateAttribute ("xmlns");
287                         attr.Value = "urn:foo";
288                         xs.UnhandledAttributes = new XmlAttribute [] {attr};
289                         xs.Write (xw);
290                         doc.LoadXml (sw.ToString ());
291                         AssertEquals ("#7", "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", doc.DocumentElement.OuterXml);
292                 }
293
294                 [Category ("NotWorking")]
295                 [Test]
296                 public void TestWriteNamespaces2 ()
297                 {
298                         string xmldecl = "<?xml version=\"1.0\" encoding=\"utf-16\"?>";
299                         XmlSchema xs = new XmlSchema ();
300                         XmlSerializerNamespaces nss =
301                                 new XmlSerializerNamespaces ();
302                         StringWriter sw;
303                         sw = new StringWriter ();
304                         xs.Write (new XmlTextWriter (sw));
305                         AssertEquals ("#1", xmldecl + "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
306
307                         xs.Namespaces = nss;
308                         sw = new StringWriter ();
309                         xs.Write (new XmlTextWriter (sw));
310                         AssertEquals ("#2", xmldecl + "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
311
312                         nss.Add ("foo", "urn:foo");
313                         sw = new StringWriter ();
314                         xs.Write (new XmlTextWriter (sw));
315                         // commenting out. .NET 2.0 outputs xs:schema instead of schema, that also makes sense.
316                         // AssertEquals ("#3", xmldecl + "<schema xmlns:foo=\"urn:foo\" xmlns=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
317
318                         nss.Add ("", "urn:foo");
319                         sw = new StringWriter ();
320                         xs.Write (new XmlTextWriter (sw));
321                         // commenting out. .NET 2.0 outputs xs:schema instead of q1:schema, that also makes sense.
322                         // AssertEquals ("#4", xmldecl + "<q1:schema xmlns:foo=\"urn:foo\" xmlns=\"urn:foo\" xmlns:q1=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
323
324                         nss.Add ("q1", "urn:q1");
325                         sw = new StringWriter ();
326                         xs.Write (new XmlTextWriter (sw));
327                         //Not sure if testing for exact order of these name spaces is
328                         // relevent, so using less strict test that passes on MS.NET
329                         //AssertEquals (xmldecl + "<q2:schema xmlns:foo=\"urn:foo\" xmlns:q1=\"urn:q1\" xmlns=\"urn:foo\" xmlns:q2=\"http://www.w3.org/2001/XMLSchema\" />", sw.ToString ());
330                         Assert("q1", sw.ToString ().IndexOf ("xmlns:q1=\"urn:q1\"") != -1);
331                 }
332
333                 [Test]
334                 public void ReaderPositionAfterRead ()
335                 {
336                         string xsd = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' elementFormDefault='qualified'>  <xs:element name='test' type='xs:integer'/></xs:schema>";
337                         XmlTextReader xtr = new XmlTextReader (xsd, XmlNodeType.Document, null);
338                         xtr.Read ();
339                         XmlSchema xs = XmlSchema.Read (xtr, null);
340                         AssertEquals (XmlNodeType.EndElement, xtr.NodeType);
341                 }
342
343                 [Test]
344                 // bug #76865
345                 public void AmbiguityDetectionOnChameleonAnyOther ()
346                 {
347                         string xsd = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
348 <xs:complexType name='TestType'>
349   <xs:sequence>
350     <xs:any namespace='##other' minOccurs='0' />
351     <xs:element name='Item' /> 
352     <xs:any namespace='##other' minOccurs='0' />
353   </xs:sequence> 
354 </xs:complexType>
355 </xs:schema>";
356                         XmlSchema.Read (new XmlTextReader (xsd, XmlNodeType.Document, null), null);
357                 }
358
359                 [Test]
360                 // bug #77685
361                 public void ReadDoesNotIgnoreDocumentationEmptyElement ()
362                 {
363                         string schemaxml = @"<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'>
364   <xs:element name='choice'>
365     <xs:annotation><xs:documentation /></xs:annotation>
366   </xs:element>
367 </xs:schema>";
368                         XmlTextReader tr = new XmlTextReader (
369                                 schemaxml, XmlNodeType.Document, null);
370                         XmlSchema schema = XmlSchema.Read (tr, null);
371                         XmlSchemaElement element =
372                                 schema.Items [0] as XmlSchemaElement;
373                         XmlSchemaAnnotation annotation = element.Annotation;
374                         XmlSchemaDocumentation doc =
375                                 annotation.Items [0] as XmlSchemaDocumentation;
376                         AssertEquals (0, doc.Markup.Length);
377                 }
378
379
380                 [Test]
381                 // bug #77687
382                 public void CompileFillsSchemaPropertyInExternal ()
383                 {
384                         string schemaFileName = "Test/XmlFiles/xsd/77687.xsd";
385                         XmlTextReader tr = new XmlTextReader (schemaFileName);
386
387                         XmlSchema schema = XmlSchema.Read (tr, null);
388                         XmlSchemaInclude inc = (XmlSchemaInclude) schema.Includes [0];
389                         AssertNull (inc.Schema);
390                         schema.Compile (null);
391                         tr.Close ();
392                         AssertNotNull (inc.Schema);
393                 }
394
395                 [Test]
396                 // bug #78985 (contains two identical field path "@key" in 
397                 // two different keys where one is in scope within another)
398                 public void DuplicateKeyFieldAttributePath ()
399                 {
400                         string schemaFileName = "Test/XmlFiles/xsd/78985.xsd";
401                         string xmlFileName = "Test/XmlFiles/xsd/78985.xml";
402                         XmlTextReader tr = new XmlTextReader (schemaFileName);
403
404                         XmlValidatingReader vr = new XmlValidatingReader (
405                                 new XmlTextReader (xmlFileName));
406                         vr.Schemas.Add (XmlSchema.Read (tr, null));
407                         while (!vr.EOF)
408                                 vr.Read ();
409                 }
410
411                 [Test]
412                 public void ThreeLevelNestedInclusion ()
413                 {
414                         XmlTextReader r = new XmlTextReader ("Test/XmlFiles/xsd/361818.xsd");
415                         try {
416                                 XmlSchema xs = XmlSchema.Read (r, null);
417                                 xs.Compile (null);
418                         } finally {
419                                 r.Close ();
420                         }
421                 }
422                 
423 #if NET_2_0
424
425                 internal class XmlTestResolver : XmlResolver
426                 {                       
427                         Uri receivedUri;
428
429                         public override ICredentials Credentials
430                         {
431                             set { throw new NotSupportedException (); }
432                         }
433
434                         public override Uri ResolveUri (Uri baseUri, string relativeUri)
435                         {
436                             return new Uri (relativeUri);
437                         }
438                         
439                         public Uri ReceivedUri
440                         {
441                                 get { return receivedUri; }
442                         }
443
444                         public override object GetEntity (Uri absoluteUri, string role, Type ofObjectToReturn)
445                         {
446                                 receivedUri = absoluteUri;
447                                 
448                                 return null;
449                         }
450                 }       
451                 
452                 [Test]
453                 public void TestResolveUri ()
454                 {
455                         XmlSchemaSet schemaSet = new XmlSchemaSet ();
456                         FileStream stream = new FileStream ("Test/XmlFiles/xsd/resolveUriSchema.xsd", FileMode.Open);
457                         schemaSet.Add ("http://tempuri.org/resolveUriSchema.xsd", new XmlTextReader (stream));
458
459                         XmlTestResolver resolver = new XmlTestResolver ();              
460                         
461                         XmlReaderSettings settings = new XmlReaderSettings ();                  
462                         settings.Schemas.XmlResolver = resolver; 
463                         settings.Schemas.Add (schemaSet);
464                         settings.ValidationType = ValidationType.Schema;
465                         settings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema | XmlSchemaValidationFlags.ProcessSchemaLocation;
466                         XmlReader reader = XmlReader.Create (stream, settings);
467                         
468                         try
469                         {
470                                 reader.Read ();         
471                         }
472                         catch (XmlException)
473                         {
474                                 // do nothing - we are expecting this exception because the test xmlresolver returns null from its 
475                                 // GetEntity method.
476                         }
477                         
478                         AssertEquals ("assembly://MyAssembly.Name/MyProjectNameSpace/objects.xsd", resolver.ReceivedUri.OriginalString);
479                 }
480
481                 [Test]
482                 public void TestImportNoSchemaLocation()
483                 {
484                         XmlSchemaSet schemaSet = new XmlSchemaSet ();
485                         schemaSet.Add (GetSchema ("Test/XmlFiles/xsd/importNamespaceTest.xsd"));
486                         schemaSet.Add (GetSchema ("Test/XmlFiles/xsd/importedNamespace.xsd"));
487                         
488                         XmlReaderSettings settings = new XmlReaderSettings ();
489                         settings.Schemas.Add (schemaSet);
490                         settings.ValidationType = ValidationType.Schema;
491                         
492                         XmlReader reader = XmlReader.Create ("Test/XmlFiles/xsd/xsdimporttest.xml", settings);
493                         
494                         // Parse the file. 
495                         while (reader.Read()) {}
496                 }
497 #endif
498         }
499 }