2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.XML / System.Xml.Schema / XmlSchemaUtil.cs
blob4b392d2bb9354135e01620d804d2c4c25b3733ed
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 using System;
23 using System.Xml;
24 using System.Collections;
25 using System.Text;
26 using Mono.Xml;
27 using Mono.Xml.Schema;
28 using System.Xml.Serialization;
30 namespace System.Xml.Schema
32 /// <summary>
33 /// All Methods in this class should use XmlConvert. Some Methods are not present in the
34 /// MS Implementation. We should provide them.
35 /// </summary>
36 internal class XmlSchemaUtil
38 static XmlSchemaUtil ()
40 FinalAllowed = XmlSchemaDerivationMethod.Restriction |
41 XmlSchemaDerivationMethod.Extension;
42 ComplexTypeBlockAllowed = FinalAllowed;
43 ElementBlockAllowed = XmlSchemaDerivationMethod.Substitution |
44 FinalAllowed;
47 internal static XmlSchemaDerivationMethod FinalAllowed;
48 internal static XmlSchemaDerivationMethod ElementBlockAllowed;
49 internal static XmlSchemaDerivationMethod ComplexTypeBlockAllowed;
50 internal static readonly bool StrictMsCompliant = Environment.GetEnvironmentVariable ("MONO_STRICT_MS_COMPLIANT") == "yes";
53 public static void AddToTable (XmlSchemaObjectTable table, XmlSchemaObject obj,
54 XmlQualifiedName qname, ValidationEventHandler h)
56 if (table.Contains (qname)) {
57 // FIXME: This logic unexpectedly allows
58 // one redefining item and two or more redefining items.
59 // FIXME: redefining item is not simple replacement,
60 // but much more complex stuff.
61 if (obj.isRedefineChild) { // take precedence.
62 if (obj.redefinedObject != null)
63 obj.error (h, String.Format ("Named item {0} was already contained in the schema object table.", qname));
64 else
65 obj.redefinedObject = table [qname];
66 table.Set (qname, obj);
68 else if (table [qname].isRedefineChild) {
69 if (table [qname].redefinedObject != null)
70 obj.error (h, String.Format ("Named item {0} was already contained in the schema object table.", qname));
71 else
72 table [qname].redefinedObject = obj;
73 return; // never add to the table.
75 else if (StrictMsCompliant) {
76 table.Set (qname, obj);
78 else
79 obj.error (h, String.Format ("Named item {0} was already contained in the schema object table. {1}",
80 qname, "Consider setting MONO_STRICT_MS_COMPLIANT to 'yes' to mimic MS implementation."));
82 else
83 table.Set (qname, obj);
86 public static void CompileID (string id, XmlSchemaObject xso, Hashtable idCollection, ValidationEventHandler h)
88 //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#ID
89 // 1. ID must be a NCName
90 // 2. ID must be unique in the schema
91 if(id == null)
92 return;
93 if(!CheckNCName(id))
94 xso.error(h,id+" is not a valid id attribute");
95 else if(idCollection.ContainsKey(id))
96 xso.error(h,"Duplicate id attribute "+id);
97 else
98 idCollection.Add(id,xso);
101 public static bool CheckAnyUri (string uri)
103 if (uri.StartsWith ("##"))
104 return false;
105 return true;
108 public static bool CheckNormalizedString (string token)
110 return true;
113 public static bool CheckNCName (string name)
115 //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#NCName
116 return XmlChar.IsNCName (name);
119 public static bool CheckQName (XmlQualifiedName qname)
121 // What is this doing?
122 return true;
125 public static XmlParserContext GetParserContext (XmlReader reader)
127 IHasXmlParserContext xctx = reader as IHasXmlParserContext;
128 if (xctx != null)
129 return xctx.ParserContext;
131 return null;
134 public static bool IsBuiltInDatatypeName (XmlQualifiedName qname)
136 if (qname.Namespace == XmlSchema.XdtNamespace) {
137 switch (qname.Name) {
138 case "anyAtomicType":
139 case "untypedAtomic":
140 case "dayTimeDuration":
141 case "yearMonthDuration":
142 return true;
143 default:
144 return false;
147 if (qname.Namespace != XmlSchema.Namespace)
148 return false;
149 switch (qname.Name) {
150 case "anySimpleType":
151 case "duration": case "dateTime": case "time":
152 case "date": case "gYearMonth": case "gYear":
153 case "gMonthDay": case "gDay": case "gMonth":
154 case "boolean":
155 case "base64Binary": case "hexBinary":
156 case "float": case "double":
157 case "anyURI":
158 case "QName":
159 case "NOTATION":
160 case "string": case "normalizedString": case "token":
161 case "language": case "Name": case "NCName":
162 case "ID": case "IDREF": case "IDREFS":
163 case "ENTITY": case "ENTITIES":
164 case "NMTOKEN": case "NMTOKENS":
165 case "decimal": case "integer":
166 case "nonPositiveInteger": case "negativeInteger":
167 case "nonNegativeInteger":
168 case "unsignedLong": case "unsignedInt":
169 case "unsignedShort": case "unsignedByte":
170 case "positiveInteger":
171 case "long": case "int": case "short": case "byte":
172 return true;
174 return false;
177 public static bool AreSchemaDatatypeEqual (XmlSchemaSimpleType st1, object v1, XmlSchemaSimpleType st2, object v2)
179 if (st1.Datatype is XsdAnySimpleType)
180 return AreSchemaDatatypeEqual (st1.Datatype as XsdAnySimpleType, v1, st2.Datatype as XsdAnySimpleType, v2);
181 // otherwise the types are lists of strings.
182 string [] a1 = v1 as string [];
183 string [] a2 = v2 as string [];
184 if (st1 != st2 || a1 == null || a2 == null || a1.Length != a2.Length)
185 return false;
186 for (int i = 0; i < a1.Length; i++)
187 if (a1 [i] != a2 [i])
188 return false;
189 return true;
192 public static bool AreSchemaDatatypeEqual (XsdAnySimpleType st1, object v1,
193 XsdAnySimpleType st2, object v2)
195 if (v1 == null || v2 == null)
196 return false;
198 if (st1 == null)
199 st1 = XmlSchemaSimpleType.AnySimpleType;
200 if (st2 == null)
201 st2 = XmlSchemaSimpleType.AnySimpleType;
203 Type t = st2.GetType ();
204 if (st1 is XsdFloat) {
205 return st2 is XsdFloat && Convert.ToSingle (v1) == Convert.ToSingle (v2);
206 } else if (st1 is XsdDouble) {
207 return st2 is XsdDouble && Convert.ToDouble (v1) == Convert.ToDouble (v2);
208 } else if (st1 is XsdDecimal) {
209 if (!(st2 is XsdDecimal) || Convert.ToDecimal (v1) != Convert.ToDecimal (v2))
210 return false;
211 if (st1 is XsdNonPositiveInteger)
212 return st2 is XsdNonPositiveInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
213 else if (st1 is XsdPositiveInteger)
214 return st2 is XsdPositiveInteger || t == typeof (XsdDecimal) ||
215 t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
216 else if (st1 is XsdUnsignedLong)
217 return st2 is XsdUnsignedLong || t == typeof (XsdDecimal) ||
218 t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
219 else if (st1 is XsdNonNegativeInteger)
220 return st2 is XsdNonNegativeInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
221 else if (st1 is XsdLong)
222 return st2 is XsdLong || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
223 return true;
225 else if (!v1.Equals (v2))
226 return false;
227 if (st1 is XsdString) {
228 if (!(st2 is XsdString))
229 return false;
230 if (st1 is XsdNMToken && (st2 is XsdLanguage || st2 is XsdName))
231 return false;
232 if (st2 is XsdNMToken && (st1 is XsdLanguage || st1 is XsdName))
233 return false;
234 if (st1 is XsdName && (st2 is XsdLanguage || st2 is XsdNMToken))
235 return false;
236 if (st2 is XsdName && (st1 is XsdLanguage || st1 is XsdNMToken))
237 return false;
238 if (st1 is XsdID && st2 is XsdIDRef)
239 return false;
240 if (st1 is XsdIDRef && st2 is XsdID)
241 return false;
243 else if (st1 != st2)
244 return false;
245 return true;
248 public static bool IsValidQName(string qname)
250 foreach(string part in qname.Split(new char[]{':'},2))
252 if(!CheckNCName(part))
253 return false;
255 return true;
258 //FIXME: First remove all the multiple instances of whitespace and then return the strings.
259 //The current method returns empty strings if there are two or more consecutive whitespaces.
260 public static string[] SplitList(string list)
262 if(list == null || list == string.Empty)
263 return new string [0];
265 ArrayList al = null;
266 int start = 0;
267 bool wait = true;
268 for (int i = 0; i < list.Length; i++) {
269 switch (list [i]) {
270 case ' ':
271 case '\r':
272 case '\n':
273 case '\t':
274 if (!wait) {
275 if (al == null)
276 al = new ArrayList ();
277 al.Add (list.Substring (start, i - start));
279 wait = true;
280 break;
281 default:
282 if (wait) {
283 wait = false;
284 start = i;
286 break;
290 if (!wait && start == 0)
291 return new string [] {list};
293 if (!wait && start < list.Length)
294 al.Add (start == 0 ? list : list.Substring (start));
295 return al.ToArray (typeof (string)) as string [];
298 public static void ReadUnhandledAttribute(XmlReader reader, XmlSchemaObject xso)
300 if(reader.Prefix == "xmlns")
301 xso.Namespaces.Add(reader.LocalName, reader.Value);
302 else if(reader.Name == "xmlns")
303 xso.Namespaces.Add("",reader.Value);
304 else
306 if(xso.unhandledAttributeList == null)
307 xso.unhandledAttributeList = new System.Collections.ArrayList();
308 XmlAttribute attr = new XmlDocument().CreateAttribute(reader.LocalName,reader.NamespaceURI);
309 attr.Value = reader.Value;
310 ParseWsdlArrayType (reader, attr);
311 xso.unhandledAttributeList.Add(attr);
315 static void ParseWsdlArrayType (XmlReader reader, XmlAttribute attr)
317 if (attr.NamespaceURI == XmlSerializer.WsdlNamespace && attr.LocalName == "arrayType")
319 string ns = "", type, dimensions;
320 TypeTranslator.ParseArrayType (attr.Value, out type, out ns, out dimensions);
321 if (ns != "") ns = reader.LookupNamespace (ns) + ":";
322 attr.Value = ns + type + dimensions;
326 public static bool ReadBoolAttribute(XmlReader reader, out Exception innerExcpetion)
328 innerExcpetion = null;
331 bool val = XmlConvert.ToBoolean(reader.Value);
332 return val;
334 catch(Exception ex)
336 innerExcpetion = ex;
337 return false;
340 public static decimal ReadDecimalAttribute(XmlReader reader, out Exception innerExcpetion)
342 innerExcpetion = null;
345 decimal val = XmlConvert.ToDecimal(reader.Value);
346 return val;
348 catch(Exception ex)
350 innerExcpetion = ex;
351 return decimal.Zero;
355 // Is some value is read, return it.
356 // If no values return empty.
357 // If exception, return none
358 public static XmlSchemaDerivationMethod ReadDerivationAttribute(XmlReader reader, out Exception innerExcpetion, string name, XmlSchemaDerivationMethod allowed)
360 innerExcpetion = null;
363 string list = reader.Value;
364 string warn = "";
365 XmlSchemaDerivationMethod val = 0;
367 if(list.IndexOf("#all") != -1 && list.Trim() != "#all")
369 innerExcpetion = new Exception(list+" is not a valid value for "+ name +". #all if present must be the only value");
370 return XmlSchemaDerivationMethod.All;
372 foreach(string xsdm in XmlSchemaUtil.SplitList(list))
374 switch(xsdm)
376 case "":
377 val = AddFlag (val, XmlSchemaDerivationMethod.Empty, allowed); break;
378 case "#all":
379 val = AddFlag (val,XmlSchemaDerivationMethod.All, allowed); break;
380 case "substitution":
381 val = AddFlag (val,XmlSchemaDerivationMethod.Substitution, allowed); break;
382 case "extension":
383 val = AddFlag (val,XmlSchemaDerivationMethod.Extension, allowed); break;
384 case "restriction":
385 val = AddFlag (val,XmlSchemaDerivationMethod.Restriction, allowed); break;
386 case "list":
387 val = AddFlag (val,XmlSchemaDerivationMethod.List, allowed); break;
388 case "union":
389 val = AddFlag (val,XmlSchemaDerivationMethod.Union, allowed); break;
390 default:
391 warn += xsdm + " "; break;
394 if(warn != "")
395 innerExcpetion = new Exception(warn + "is/are not valid values for " + name);
396 return val;
398 catch(Exception ex)
400 innerExcpetion = ex;
401 return XmlSchemaDerivationMethod.None;
405 private static XmlSchemaDerivationMethod AddFlag (XmlSchemaDerivationMethod dst,
406 XmlSchemaDerivationMethod add, XmlSchemaDerivationMethod allowed)
408 if ((add & allowed) == 0 && allowed != XmlSchemaDerivationMethod.All)
409 throw new ArgumentException (add + " is not allowed in this attribute.");
410 if ((dst & add) != 0)
411 throw new ArgumentException (add + " is already specified in this attribute.");
412 return dst | add;
415 public static XmlSchemaForm ReadFormAttribute(XmlReader reader, out Exception innerExcpetion)
417 innerExcpetion = null;
418 XmlSchemaForm val = XmlSchemaForm.None;
419 switch(reader.Value)
421 case "qualified":
422 val = XmlSchemaForm.Qualified; break;
423 case "unqualified":
424 val = XmlSchemaForm.Unqualified; break;
425 default:
426 innerExcpetion = new Exception("only qualified or unqulified is a valid value"); break;
428 return val;
431 public static XmlSchemaContentProcessing ReadProcessingAttribute(XmlReader reader, out Exception innerExcpetion)
433 innerExcpetion = null;
434 XmlSchemaContentProcessing val = XmlSchemaContentProcessing.None;
435 switch(reader.Value)
437 case "lax":
438 val = XmlSchemaContentProcessing.Lax; break;
439 case "strict":
440 val = XmlSchemaContentProcessing.Strict; break;
441 case "skip":
442 val = XmlSchemaContentProcessing.Skip; break;
443 default:
444 innerExcpetion = new Exception("only lax , strict or skip are valid values for processContents");
445 break;
447 return val;
450 public static XmlSchemaUse ReadUseAttribute(XmlReader reader, out Exception innerExcpetion)
452 innerExcpetion = null;
453 XmlSchemaUse val = XmlSchemaUse.None;
454 switch(reader.Value)
456 case "optional":
457 val = XmlSchemaUse.Optional; break;
458 case "prohibited":
459 val = XmlSchemaUse.Prohibited; break;
460 case "required":
461 val = XmlSchemaUse.Required; break;
462 default:
463 innerExcpetion = new Exception("only optional , prohibited or required are valid values for use");
464 break;
466 return val;
468 public static XmlQualifiedName ReadQNameAttribute(XmlReader reader, out Exception innerEx)
470 return ToQName(reader, reader.Value, out innerEx);
473 //While Creating a XmlQualifedName, we should check:
474 // 1. If a prefix is present, its namespace should be resolvable.
475 // 2. If a prefix is not present, and if the defaultNamespace is set,
476 public static XmlQualifiedName ToQName(XmlReader reader, string qnamestr, out Exception innerEx)
479 string ns;
480 string name;
481 XmlQualifiedName qname;
482 innerEx = null;
484 if(!IsValidQName(qnamestr))
486 innerEx = new Exception(qnamestr + " is an invalid QName. Either name or namespace is not a NCName");
487 return XmlQualifiedName.Empty;
490 string[] values = qnamestr.Split(new char[]{':'},2);
492 if(values.Length == 2)
494 ns = reader.LookupNamespace(values[0]);
495 if(ns == null)
497 innerEx = new Exception("Namespace Prefix '"+values[0]+"could not be resolved");
498 return XmlQualifiedName.Empty;
500 name = values[1];
502 else
504 //Default Namespace
505 ns = reader.LookupNamespace("");
506 name = values[0];
509 qname = new XmlQualifiedName(name,ns);
510 return qname;
513 public static int ValidateAttributesResolved (
514 XmlSchemaObjectTable attributesResolved,
515 ValidationEventHandler h,
516 XmlSchema schema,
517 XmlSchemaObjectCollection attributes,
518 XmlSchemaAnyAttribute anyAttribute,
519 ref XmlSchemaAnyAttribute anyAttributeUse,
520 XmlSchemaAttributeGroup redefined,
521 bool skipEquivalent)
523 int errorCount = 0;
524 if (anyAttribute != null && anyAttributeUse == null)
525 anyAttributeUse = anyAttribute;
527 ArrayList newAttrNames = new ArrayList ();
529 foreach (XmlSchemaObject xsobj in attributes) {
530 XmlSchemaAttributeGroupRef grpRef = xsobj as XmlSchemaAttributeGroupRef;
531 if (grpRef != null) {
532 // Resolve attributeGroup redefinition.
533 XmlSchemaAttributeGroup grp = null;
534 if (redefined != null && grpRef.RefName == redefined.QualifiedName)
535 grp = redefined;
536 else
537 grp = schema.FindAttributeGroup (grpRef.RefName);
538 // otherwise, it might be missing sub components.
539 if (grp == null) {
540 if (!schema.missedSubComponents)// && schema.Schemas [grpRef.RefName.Namespace] != null)
541 grpRef.error (h, "Referenced attribute group " + grpRef.RefName + " was not found in the corresponding schema.");
542 continue;
544 if (grp.AttributeGroupRecursionCheck) {
545 grp.error (h, "Attribute group recursion was found: " + grpRef.RefName);
546 continue;
548 try {
549 grp.AttributeGroupRecursionCheck = true;
550 errorCount += grp.Validate (h, schema);
551 } finally {
552 grp.AttributeGroupRecursionCheck = false;
554 if (grp.AnyAttributeUse != null) {
555 if (anyAttribute == null)
556 anyAttributeUse = grp.AnyAttributeUse;
558 foreach (DictionaryEntry entry in grp.AttributeUses) {
559 XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
561 if (StrictMsCompliant && attr.Use == XmlSchemaUse.Prohibited)
562 continue;
564 if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty && (!skipEquivalent || !AreAttributesEqual (attr, attributesResolved [attr.RefName] as XmlSchemaAttribute)))
565 AddToTable (attributesResolved, attr, attr.RefName, h);
566 else if (!skipEquivalent || !AreAttributesEqual (attr, attributesResolved [attr.QualifiedName] as XmlSchemaAttribute))
567 AddToTable (attributesResolved, attr, attr.QualifiedName, h);
569 } else {
570 XmlSchemaAttribute attr = xsobj as XmlSchemaAttribute;
571 if (attr != null) {
572 errorCount += attr.Validate (h, schema);
574 if (newAttrNames.Contains (attr.QualifiedName))
575 attr.error (h, String.Format ("Duplicate attributes was found for '{0}'", attr.QualifiedName));
576 newAttrNames.Add (attr.QualifiedName);
579 if (StrictMsCompliant && attr.Use == XmlSchemaUse.Prohibited)
580 continue;
582 if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty && (!skipEquivalent || !AreAttributesEqual (attr, attributesResolved [attr.RefName] as XmlSchemaAttribute)))
583 AddToTable (attributesResolved, attr, attr.RefName, h);
584 else if (!skipEquivalent || !AreAttributesEqual (attr, attributesResolved [attr.QualifiedName] as XmlSchemaAttribute))
585 AddToTable (attributesResolved, attr, attr.QualifiedName, h);
586 } else {
587 if (anyAttribute == null) {
588 anyAttributeUse = (XmlSchemaAnyAttribute) xsobj;
589 anyAttribute.Validate (h, schema);
594 return errorCount;
597 internal static bool AreAttributesEqual (XmlSchemaAttribute one,
598 XmlSchemaAttribute another)
600 if (one == null || another == null)
601 return false;
602 return one.AttributeType == another.AttributeType &&
603 one.Form == another.Form &&
604 one.ValidatedUse == another.ValidatedUse &&
605 one.ValidatedDefaultValue == another.ValidatedDefaultValue &&
606 one.ValidatedFixedValue == another.ValidatedFixedValue;
609 #if NET_2_0
610 public static object ReadTypedValue (XmlReader reader,
611 object type, IXmlNamespaceResolver nsResolver,
612 StringBuilder tmpBuilder)
613 #else
614 public static object ReadTypedValue (XmlReader reader,
615 object type, XmlNamespaceManager nsResolver,
616 StringBuilder tmpBuilder)
617 #endif
619 if (tmpBuilder == null)
620 tmpBuilder = new StringBuilder ();
621 XmlSchemaDatatype dt = type as XmlSchemaDatatype;
622 XmlSchemaSimpleType st = type as XmlSchemaSimpleType;
623 if (st != null)
624 dt = st.Datatype;
625 if (dt == null)
626 return null;
628 switch (reader.NodeType) {
629 case XmlNodeType.Element:
630 if (reader.IsEmptyElement)
631 return null;
633 tmpBuilder.Length = 0;
634 bool loop = true;
635 do {
636 reader.Read ();
637 switch (reader.NodeType) {
638 case XmlNodeType.SignificantWhitespace:
639 case XmlNodeType.Text:
640 case XmlNodeType.CDATA:
641 tmpBuilder.Append (reader.Value);
642 break;
643 case XmlNodeType.Comment:
644 break;
645 default:
646 loop = false;
647 break;
649 } while (loop && !reader.EOF && reader.ReadState == ReadState.Interactive);
650 return dt.ParseValue (tmpBuilder.ToString (), reader.NameTable, nsResolver);
651 case XmlNodeType.Attribute:
652 return dt.ParseValue (reader.Value, reader.NameTable, nsResolver);
654 return null;
657 public static XmlSchemaObject FindAttributeDeclaration (
658 string ns,
659 XmlSchemaSet schemas,
660 XmlSchemaComplexType cType,
661 XmlQualifiedName qname)
663 XmlSchemaObject result = cType.AttributeUses [qname];
664 if (result != null)
665 return result;
666 if (cType.AttributeWildcard == null)
667 return null;
669 if (!AttributeWildcardItemValid (cType.AttributeWildcard, qname, ns))
670 return null;
672 if (cType.AttributeWildcard.ResolvedProcessContents == XmlSchemaContentProcessing.Skip)
673 return cType.AttributeWildcard;
674 XmlSchemaAttribute attr = schemas.GlobalAttributes [qname] as XmlSchemaAttribute;
675 if (attr != null)
676 return attr;
677 if (cType.AttributeWildcard.ResolvedProcessContents == XmlSchemaContentProcessing.Lax)
678 return cType.AttributeWildcard;
679 else
680 return null;
683 // Spec 3.10.4 Item Valid (Wildcard)
684 private static bool AttributeWildcardItemValid (XmlSchemaAnyAttribute anyAttr, XmlQualifiedName qname, string ns)
686 if (anyAttr.HasValueAny)
687 return true;
688 if (anyAttr.HasValueOther && (anyAttr.TargetNamespace == "" || ns != anyAttr.TargetNamespace))
689 return true;
690 if (anyAttr.HasValueTargetNamespace && ns == anyAttr.TargetNamespace)
691 return true;
692 if (anyAttr.HasValueLocal && ns == "")
693 return true;
694 for (int i = 0; i < anyAttr.ResolvedNamespaces.Count; i++)
695 if (anyAttr.ResolvedNamespaces [i] == ns)
696 return true;
697 return false;