using System; using System.Xml; using System.Collections; using Mono.Xml; using Mono.Xml.Schema; using System.Xml.Serialization; namespace System.Xml.Schema { /// /// All Methods in this class should use XmlConvert. Some Methods are not present in the /// MS Implementation. We should provide them. /// internal class XmlSchemaUtil { static XmlSchemaUtil() { FinalAllowed = XmlSchemaDerivationMethod.Restriction | XmlSchemaDerivationMethod.Extension; ComplexTypeBlockAllowed = FinalAllowed; ElementBlockAllowed = XmlSchemaDerivationMethod.Substitution | FinalAllowed; } internal static XmlSchemaDerivationMethod FinalAllowed; internal static XmlSchemaDerivationMethod ElementBlockAllowed; internal static XmlSchemaDerivationMethod ComplexTypeBlockAllowed; public static void AddToTable (XmlSchemaObjectTable table, XmlSchemaObject obj, XmlQualifiedName qname, ValidationEventHandler h) { if (table.Contains (qname)) { // FIXME: This logic unexpectedly allows // one redefining item and two or more redefining items. // FIXME: redefining item is not simple replacement, // but much more complex stuff. if (obj.isRedefineChild) { // take precedence. if (obj.redefinedObject != null) obj.error (h, "Named item " + qname + " was already contained in the schema object table."); else obj.redefinedObject = table [qname]; table.Set (qname, obj); } else if (table [qname].isRedefineChild) { if (table [qname].redefinedObject != null) obj.error (h, "Named item " + qname + " was already contained in the schema object table."); else table [qname].redefinedObject = obj; return; // never add to the table. } else obj.error (h, "Named item " + qname + " was already contained in the schema object table."); } else table.Set (qname, obj); } public static void CompileID(string id, XmlSchemaObject xso, Hashtable idCollection, ValidationEventHandler h) { //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#ID // 1. ID must be a NCName // 2. ID must be unique in the schema if(id == null) return; if(!CheckNCName(id)) xso.error(h,id+" is not a valid id attribute"); else if(idCollection.ContainsKey(id)) xso.error(h,"Duplicate id attribute "+id); else idCollection.Add(id,xso); } [MonoTODO] public static bool CheckAnyUri(string uri) { if (uri.StartsWith ("##")) return false; return true; } public static bool CheckToken(string token) { //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#token return true; } public static bool CheckNormalizedString(string token) { return true; } public static bool CheckLanguage(string lang) { //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#language return true; } public static bool CheckNCName(string name) { //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#NCName try { XmlConvert.VerifyNCName(name); return true; } catch(Exception ex) { return false; } } public static bool CheckQName(XmlQualifiedName qname) { // What is this doing? return true; } public static XmlParserContext GetParserContext (XmlReader reader) { XmlTextReader xtr = reader as XmlTextReader; if (xtr != null) return xtr.GetInternalParserContext (); XmlNodeReader xnr = reader as XmlNodeReader; if (xnr != null) return xnr.GetInternalParserContext (); XmlValidatingReader xvr = reader as XmlValidatingReader; if (xvr != null) return xvr.GetInternalParserContext (); IHasXmlParserContext xctx = reader as IHasXmlParserContext; if (xctx != null) return xctx.ParserContext; throw new NotSupportedException ("XmlParserContext cannot be acquired from this XmlReader."); } public static bool IsSchemaDatatypeEquals (XsdAnySimpleType st1, object v1, XsdAnySimpleType st2, object v2) { if (v1 == null || v2 == null) return false; if (st1 == null) st1 = XmlSchemaSimpleType.AnySimpleType; if (st2 == null) st2 = XmlSchemaSimpleType.AnySimpleType; Type t = st2.GetType (); if (st1 is XsdFloat) { return st2 is XsdFloat && Convert.ToSingle (v1) == Convert.ToSingle (v2); } else if (st1 is XsdDouble) { return st2 is XsdDouble && Convert.ToDouble (v1) == Convert.ToDouble (v2); } else if (st1 is XsdDecimal) { if (!(st2 is XsdDecimal) || Convert.ToDecimal (v1) != Convert.ToDecimal (v2)) return false; if (st1 is XsdNonPositiveInteger) return st2 is XsdNonPositiveInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger); else if (st1 is XsdPositiveInteger) return st2 is XsdPositiveInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger); else if (st1 is XsdUnsignedLong) return st2 is XsdUnsignedLong || t == typeof (XsdDecimal) || t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger); else if (st1 is XsdNonNegativeInteger) return st2 is XsdNonNegativeInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger); else if (st1 is XsdLong) return st2 is XsdLong || t == typeof (XsdDecimal) || t == typeof (XsdInteger); return true; } else if (!v1.Equals (v2)) return false; if (st1 is XsdString) { if (!(st2 is XsdString)) return false; if (st1 is XsdNMToken && (st2 is XsdLanguage || st2 is XsdName)) return false; if (st2 is XsdNMToken && (st1 is XsdLanguage || st1 is XsdName)) return false; if (st1 is XsdName && (st2 is XsdLanguage || st2 is XsdNMToken)) return false; if (st2 is XsdName && (st1 is XsdLanguage || st1 is XsdNMToken)) return false; } else if (st1 != st2) return false; return true; } public static bool IsValidQName(string qname) { foreach(string part in qname.Split(new char[]{':'},2)) { if(!CheckNCName(part)) return false; } return true; } //FIXME: First remove all the multiple instances of whitespace and then return the strings. //The current method returns empty strings if there are two or more consecutive whitespaces. public static string[] SplitList(string list) { if(list == null || list == string.Empty) return new string [0]; string[] listarr = list.Split(new char[]{' ','\t','\n'}); int pos=0; int i = 0; for(i=0;i