XmlSchemaUtil.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using System;
  2. using System.Xml;
  3. using System.Collections;
  4. namespace System.Xml.Schema
  5. {
  6. /// <summary>
  7. /// All Methods in this class should use XmlConvert. Some Methods are not present in the
  8. /// MS Implementation. We should provide them.
  9. /// </summary>
  10. internal class XmlSchemaUtil
  11. {
  12. private XmlSchemaUtil()
  13. {}
  14. public static void CompileID(string id, XmlSchemaObject xso, Hashtable idCollection, ValidationEventHandler h)
  15. {
  16. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#ID
  17. // 1. ID must be a NCName
  18. // 2. ID must be unique in the schema
  19. if(id == null)
  20. return;
  21. if(!CheckNCName(id))
  22. xso.error(h,id+" is not a valid id attribute");
  23. else if(idCollection.ContainsKey(id))
  24. xso.error(h,"Duplicate id attribute "+id);
  25. else
  26. idCollection.Add(id,xso);
  27. }
  28. [MonoTODO]
  29. public static bool CheckAnyUri(string uri)
  30. {
  31. return true;
  32. }
  33. public static bool CheckToken(string token)
  34. {
  35. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#token
  36. return true;
  37. }
  38. public static bool CheckNormalizedString(string token)
  39. {
  40. return true;
  41. }
  42. public static bool CheckLanguage(string lang)
  43. {
  44. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#language
  45. return true;
  46. }
  47. public static bool CheckNCName(string name)
  48. {
  49. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#NCName
  50. try
  51. {
  52. XmlConvert.VerifyNCName(name);
  53. return true;
  54. }
  55. catch(Exception ex)
  56. {
  57. return false;
  58. }
  59. }
  60. public static bool CheckQName(XmlQualifiedName qname)
  61. {
  62. return true;
  63. }
  64. public static bool IsValidQName(string qname)
  65. {
  66. foreach(string part in qname.Split(new char[]{':'},2))
  67. {
  68. if(!CheckNCName(part))
  69. return false;
  70. }
  71. return true;
  72. }
  73. //FIXME: First remove all the multiple instances of whitespace and then return the strings.
  74. //The current method returns empty strings if there are two or more consecutive whitespaces.
  75. public static string[] SplitList(string list)
  76. {
  77. if(list == null || list == string.Empty)
  78. return new String[0];
  79. string[] listarr = list.Split(new char[]{' ','\t','\n'});
  80. int pos=0;
  81. int i = 0;
  82. for(i=0;i<listarr.Length;i++)
  83. {
  84. if(listarr[i] != null && listarr[i] != String.Empty)
  85. {
  86. listarr[pos++] = listarr[i];
  87. }
  88. }
  89. if(pos == i)
  90. return listarr;
  91. string[] retarr = new String[pos];
  92. if(pos!=0)
  93. Array.Copy(listarr, retarr, pos);
  94. return retarr;
  95. }
  96. public static void ReadUnhandledAttribute(XmlReader reader, XmlSchemaObject xso)
  97. {
  98. if(reader.Prefix == "xmlns")
  99. xso.Namespaces.Add(reader.LocalName, reader.Value);
  100. else if(reader.Name == "xmlns")
  101. xso.Namespaces.Add("",reader.Value);
  102. else
  103. {
  104. if(xso.unhandledAttributeList == null)
  105. xso.unhandledAttributeList = new System.Collections.ArrayList();
  106. XmlAttribute attr = new XmlDocument().CreateAttribute(reader.LocalName,reader.NamespaceURI);
  107. attr.Value = reader.Value;
  108. xso.unhandledAttributeList.Add(attr);
  109. }
  110. }
  111. public static bool ReadBoolAttribute(XmlReader reader, out Exception innerExcpetion)
  112. {
  113. innerExcpetion = null;
  114. try
  115. {
  116. bool val = XmlConvert.ToBoolean(reader.Value);
  117. return val;
  118. }
  119. catch(Exception ex)
  120. {
  121. innerExcpetion = ex;
  122. return false;
  123. }
  124. }
  125. public static decimal ReadDecimalAttribute(XmlReader reader, out Exception innerExcpetion)
  126. {
  127. innerExcpetion = null;
  128. try
  129. {
  130. decimal val = XmlConvert.ToDecimal(reader.Value);
  131. return val;
  132. }
  133. catch(Exception ex)
  134. {
  135. innerExcpetion = ex;
  136. return decimal.Zero;
  137. }
  138. }
  139. // Is some value is read, return it.
  140. // If no values return empty.
  141. // If exception, return none
  142. public static XmlSchemaDerivationMethod ReadDerivationAttribute(XmlReader reader, out Exception innerExcpetion, string name)
  143. {
  144. innerExcpetion = null;
  145. try
  146. {
  147. string list = reader.Value;
  148. string warn = "";
  149. XmlSchemaDerivationMethod val = 0;
  150. if(list.IndexOf("#all") != -1 && list.Trim() != "#all")
  151. {
  152. innerExcpetion = new Exception(list+" is not a valid value for "+ name +". #all if present must be the only value");
  153. return XmlSchemaDerivationMethod.All;
  154. }
  155. foreach(string xsdm in XmlSchemaUtil.SplitList(list))
  156. {
  157. switch(xsdm)
  158. {
  159. case "":
  160. val |= XmlSchemaDerivationMethod.Empty; break;
  161. case "#all":
  162. val |= XmlSchemaDerivationMethod.All; break;
  163. case "substitution":
  164. val |= XmlSchemaDerivationMethod.Substitution; break;
  165. case "extension":
  166. val |= XmlSchemaDerivationMethod.Extension; break;
  167. case "restriction":
  168. val |= XmlSchemaDerivationMethod.Restriction; break;
  169. case "list":
  170. val |= XmlSchemaDerivationMethod.List; break;
  171. case "union":
  172. val |= XmlSchemaDerivationMethod.Union; break;
  173. default:
  174. warn += xsdm + " "; break;
  175. }
  176. }
  177. if(warn != "")
  178. innerExcpetion = new Exception(warn + "is/are not valid values for " + name);
  179. return val;
  180. }
  181. catch(Exception ex)
  182. {
  183. innerExcpetion = ex;
  184. return XmlSchemaDerivationMethod.None;
  185. }
  186. }
  187. public static XmlSchemaForm ReadFormAttribute(XmlReader reader, out Exception innerExcpetion)
  188. {
  189. innerExcpetion = null;
  190. XmlSchemaForm val = XmlSchemaForm.None;
  191. switch(reader.Value)
  192. {
  193. case "qualified":
  194. val = XmlSchemaForm.Qualified; break;
  195. case "unqualified":
  196. val = XmlSchemaForm.Unqualified; break;
  197. default:
  198. innerExcpetion = new Exception("only qualified or unqulified is a valid value"); break;
  199. }
  200. return val;
  201. }
  202. public static XmlSchemaContentProcessing ReadProcessingAttribute(XmlReader reader, out Exception innerExcpetion)
  203. {
  204. innerExcpetion = null;
  205. XmlSchemaContentProcessing val = XmlSchemaContentProcessing.None;
  206. switch(reader.Value)
  207. {
  208. case "lax":
  209. val = XmlSchemaContentProcessing.Lax; break;
  210. case "strict":
  211. val = XmlSchemaContentProcessing.Strict; break;
  212. case "skip":
  213. val = XmlSchemaContentProcessing.Skip; break;
  214. default:
  215. innerExcpetion = new Exception("only lax , strict or skip are valid values for processContents");
  216. break;
  217. }
  218. return val;
  219. }
  220. public static XmlSchemaUse ReadUseAttribute(XmlReader reader, out Exception innerExcpetion)
  221. {
  222. innerExcpetion = null;
  223. XmlSchemaUse val = XmlSchemaUse.None;
  224. switch(reader.Value)
  225. {
  226. case "optional":
  227. val = XmlSchemaUse.Optional; break;
  228. case "prohibited":
  229. val = XmlSchemaUse.Prohibited; break;
  230. case "required":
  231. val = XmlSchemaUse.Required; break;
  232. default:
  233. innerExcpetion = new Exception("only optional , prohibited or required are valid values for use");
  234. break;
  235. }
  236. return val;
  237. }
  238. public static XmlQualifiedName ReadQNameAttribute(XmlReader reader, out Exception innerEx)
  239. {
  240. return ToQName(reader, reader.Value, out innerEx);
  241. }
  242. //While Creating a XmlQualifedName, we should check:
  243. // 1. If a prefix is present, its namespace should be resolvable.
  244. // 2. If a prefix is not present, and if the defaultNamespace is set,
  245. public static XmlQualifiedName ToQName(XmlReader reader, string qnamestr, out Exception innerEx)
  246. {
  247. string ns;
  248. string name;
  249. XmlQualifiedName qname;
  250. innerEx = null;
  251. if(!IsValidQName(qnamestr))
  252. {
  253. innerEx = new Exception(qnamestr + " is an invalid QName. Either name or namespace is not a NCName");
  254. return XmlQualifiedName.Empty;
  255. }
  256. string[] values = qnamestr.Split(new char[]{':'},2);
  257. if(values.Length == 2)
  258. {
  259. ns = reader.LookupNamespace(values[0]);
  260. if(ns == null)
  261. {
  262. innerEx = new Exception("Namespace Prefix '"+values[0]+"could not be resolved");
  263. return XmlQualifiedName.Empty;
  264. }
  265. name = values[1];
  266. }
  267. else
  268. {
  269. //Default Namespace
  270. ns = reader.LookupNamespace("");
  271. name = values[0];
  272. }
  273. qname = new XmlQualifiedName(name,ns);
  274. return qname;
  275. }
  276. }
  277. }