XmlSchemaUtil.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. //
  2. // Permission is hereby granted, free of charge, to any person obtaining
  3. // a copy of this software and associated documentation files (the
  4. // "Software"), to deal in the Software without restriction, including
  5. // without limitation the rights to use, copy, modify, merge, publish,
  6. // distribute, sublicense, and/or sell copies of the Software, and to
  7. // permit persons to whom the Software is furnished to do so, subject to
  8. // the following conditions:
  9. //
  10. // The above copyright notice and this permission notice shall be
  11. // included in all copies or substantial portions of the Software.
  12. //
  13. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  17. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  18. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  19. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. //
  21. using System;
  22. using System.Xml;
  23. using System.Collections;
  24. using System.Text;
  25. using Mono.Xml;
  26. using Mono.Xml.Schema;
  27. using System.Xml.Serialization;
  28. namespace System.Xml.Schema
  29. {
  30. /// <summary>
  31. /// All Methods in this class should use XmlConvert. Some Methods are not present in the
  32. /// MS Implementation. We should provide them.
  33. /// </summary>
  34. internal class XmlSchemaUtil
  35. {
  36. static XmlSchemaUtil ()
  37. {
  38. FinalAllowed = XmlSchemaDerivationMethod.Restriction |
  39. XmlSchemaDerivationMethod.Extension;
  40. ComplexTypeBlockAllowed = FinalAllowed;
  41. ElementBlockAllowed = XmlSchemaDerivationMethod.Substitution |
  42. FinalAllowed;
  43. }
  44. internal static XmlSchemaDerivationMethod FinalAllowed;
  45. internal static XmlSchemaDerivationMethod ElementBlockAllowed;
  46. internal static XmlSchemaDerivationMethod ComplexTypeBlockAllowed;
  47. public static void AddToTable (XmlSchemaObjectTable table, XmlSchemaObject obj,
  48. XmlQualifiedName qname, ValidationEventHandler h)
  49. {
  50. if (table.Contains (qname)) {
  51. // FIXME: This logic unexpectedly allows
  52. // one redefining item and two or more redefining items.
  53. // FIXME: redefining item is not simple replacement,
  54. // but much more complex stuff.
  55. if (obj.isRedefineChild) { // take precedence.
  56. if (obj.redefinedObject != null)
  57. obj.error (h, String.Format ("Named item {0} was already contained in the schema object table.", qname));
  58. else
  59. obj.redefinedObject = table [qname];
  60. table.Set (qname, obj);
  61. }
  62. else if (table [qname].isRedefineChild) {
  63. if (table [qname].redefinedObject != null)
  64. obj.error (h, String.Format ("Named item {0} was already contained in the schema object table.", qname));
  65. else
  66. table [qname].redefinedObject = obj;
  67. return; // never add to the table.
  68. }
  69. else
  70. obj.error (h, String.Format ("Named item {0} was already contained in the schema object table.", qname));
  71. }
  72. else
  73. table.Set (qname, obj);
  74. }
  75. public static void CompileID (string id, XmlSchemaObject xso, Hashtable idCollection, ValidationEventHandler h)
  76. {
  77. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#ID
  78. // 1. ID must be a NCName
  79. // 2. ID must be unique in the schema
  80. if(id == null)
  81. return;
  82. if(!CheckNCName(id))
  83. xso.error(h,id+" is not a valid id attribute");
  84. else if(idCollection.ContainsKey(id))
  85. xso.error(h,"Duplicate id attribute "+id);
  86. else
  87. idCollection.Add(id,xso);
  88. }
  89. public static bool CheckAnyUri (string uri)
  90. {
  91. if (uri.StartsWith ("##"))
  92. return false;
  93. return true;
  94. }
  95. public static bool CheckNormalizedString (string token)
  96. {
  97. return true;
  98. }
  99. public static bool CheckNCName (string name)
  100. {
  101. //check if the string conforms to http://www.w3.org/TR/2001/REC-xmlschema-2-20010502/datatypes.html#NCName
  102. return XmlChar.IsNCName (name);
  103. }
  104. public static bool CheckQName (XmlQualifiedName qname)
  105. {
  106. // What is this doing?
  107. return true;
  108. }
  109. public static XmlParserContext GetParserContext (XmlReader reader)
  110. {
  111. IHasXmlParserContext xctx = reader as IHasXmlParserContext;
  112. if (xctx != null)
  113. return xctx.ParserContext;
  114. throw new NotSupportedException ("XmlParserContext cannot be acquired from this XmlReader.");
  115. }
  116. public static bool IsBuiltInDatatypeName (XmlQualifiedName qname)
  117. {
  118. if (qname.Namespace == XmlSchema.XdtNamespace) {
  119. switch (qname.Name) {
  120. case "anyAtomicType":
  121. case "untypedAtomic":
  122. case "dayTimeDuration":
  123. case "yearMonthDuration":
  124. return true;
  125. default:
  126. return false;
  127. }
  128. }
  129. if (qname.Namespace != XmlSchema.Namespace)
  130. return false;
  131. switch (qname.Name) {
  132. case "anySimpleType":
  133. case "duration": case "dateTime": case "time":
  134. case "date": case "gYearMonth": case "gYear":
  135. case "gMonthDay": case "gDay": case "gMonth":
  136. case "boolean":
  137. case "base64Binary": case "hexBinary":
  138. case "float": case "double":
  139. case "anyURI":
  140. case "QName":
  141. case "NOTATION":
  142. case "string": case "normalizedString": case "token":
  143. case "language": case "Name": case "NCName":
  144. case "ID": case "IDREF": case "IDREFS":
  145. case "ENTITY": case "ENTITIES":
  146. case "NMTOKEN": case "NMTOKENS":
  147. case "decimal": case "integer":
  148. case "nonPositiveInteger": case "negativeInteger":
  149. case "nonNegativeInteger":
  150. case "unsignedLong": case "unsignedInt":
  151. case "unsignedShort": case "unsignedByte":
  152. case "positiveInteger":
  153. case "long": case "int": case "short": case "byte":
  154. return true;
  155. }
  156. return false;
  157. }
  158. public static bool IsSchemaDatatypeEquals (XsdAnySimpleType st1, object v1,
  159. XsdAnySimpleType st2, object v2)
  160. {
  161. if (v1 == null || v2 == null)
  162. return false;
  163. if (st1 == null)
  164. st1 = XmlSchemaSimpleType.AnySimpleType;
  165. if (st2 == null)
  166. st2 = XmlSchemaSimpleType.AnySimpleType;
  167. Type t = st2.GetType ();
  168. if (st1 is XsdFloat) {
  169. return st2 is XsdFloat && Convert.ToSingle (v1) == Convert.ToSingle (v2);
  170. } else if (st1 is XsdDouble) {
  171. return st2 is XsdDouble && Convert.ToDouble (v1) == Convert.ToDouble (v2);
  172. } else if (st1 is XsdDecimal) {
  173. if (!(st2 is XsdDecimal) || Convert.ToDecimal (v1) != Convert.ToDecimal (v2))
  174. return false;
  175. if (st1 is XsdNonPositiveInteger)
  176. return st2 is XsdNonPositiveInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
  177. else if (st1 is XsdPositiveInteger)
  178. return st2 is XsdPositiveInteger || t == typeof (XsdDecimal) ||
  179. t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
  180. else if (st1 is XsdUnsignedLong)
  181. return st2 is XsdUnsignedLong || t == typeof (XsdDecimal) ||
  182. t == typeof (XsdInteger) || t == typeof (XsdNonNegativeInteger);
  183. else if (st1 is XsdNonNegativeInteger)
  184. return st2 is XsdNonNegativeInteger || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
  185. else if (st1 is XsdLong)
  186. return st2 is XsdLong || t == typeof (XsdDecimal) || t == typeof (XsdInteger);
  187. return true;
  188. }
  189. else if (!v1.Equals (v2))
  190. return false;
  191. if (st1 is XsdString) {
  192. if (!(st2 is XsdString))
  193. return false;
  194. if (st1 is XsdNMToken && (st2 is XsdLanguage || st2 is XsdName))
  195. return false;
  196. if (st2 is XsdNMToken && (st1 is XsdLanguage || st1 is XsdName))
  197. return false;
  198. if (st1 is XsdName && (st2 is XsdLanguage || st2 is XsdNMToken))
  199. return false;
  200. if (st2 is XsdName && (st1 is XsdLanguage || st1 is XsdNMToken))
  201. return false;
  202. if (st1 is XsdID && st2 is XsdIDRef)
  203. return false;
  204. if (st1 is XsdIDRef && st2 is XsdID)
  205. return false;
  206. }
  207. else if (st1 != st2)
  208. return false;
  209. return true;
  210. }
  211. public static bool IsValidQName(string qname)
  212. {
  213. foreach(string part in qname.Split(new char[]{':'},2))
  214. {
  215. if(!CheckNCName(part))
  216. return false;
  217. }
  218. return true;
  219. }
  220. //FIXME: First remove all the multiple instances of whitespace and then return the strings.
  221. //The current method returns empty strings if there are two or more consecutive whitespaces.
  222. public static string[] SplitList(string list)
  223. {
  224. if(list == null || list == string.Empty)
  225. return new string [0];
  226. ArrayList al = null;
  227. int start = 0;
  228. bool wait = true;
  229. for (int i = 0; i < list.Length; i++) {
  230. switch (list [i]) {
  231. case ' ':
  232. case '\r':
  233. case '\n':
  234. case '\t':
  235. if (!wait) {
  236. if (al == null)
  237. al = new ArrayList ();
  238. al.Add (list.Substring (start, i - start));
  239. }
  240. wait = true;
  241. break;
  242. default:
  243. if (wait) {
  244. wait = false;
  245. start = i;
  246. }
  247. break;
  248. }
  249. }
  250. if (!wait && start == 0)
  251. return new string [] {list};
  252. if (!wait && start < list.Length)
  253. al.Add (start == 0 ? list : list.Substring (start));
  254. return al.ToArray (typeof (string)) as string [];
  255. }
  256. public static void ReadUnhandledAttribute(XmlReader reader, XmlSchemaObject xso)
  257. {
  258. if(reader.Prefix == "xmlns")
  259. xso.Namespaces.Add(reader.LocalName, reader.Value);
  260. else if(reader.Name == "xmlns")
  261. xso.Namespaces.Add("",reader.Value);
  262. else
  263. {
  264. if(xso.unhandledAttributeList == null)
  265. xso.unhandledAttributeList = new System.Collections.ArrayList();
  266. XmlAttribute attr = new XmlDocument().CreateAttribute(reader.LocalName,reader.NamespaceURI);
  267. attr.Value = reader.Value;
  268. ParseWsdlArrayType (reader, attr);
  269. xso.unhandledAttributeList.Add(attr);
  270. }
  271. }
  272. static void ParseWsdlArrayType (XmlReader reader, XmlAttribute attr)
  273. {
  274. if (attr.NamespaceURI == XmlSerializer.WsdlNamespace && attr.LocalName == "arrayType")
  275. {
  276. string ns = "", type, dimensions;
  277. TypeTranslator.ParseArrayType (attr.Value, out type, out ns, out dimensions);
  278. if (ns != "") ns = reader.LookupNamespace (ns) + ":";
  279. attr.Value = ns + type + dimensions;
  280. }
  281. }
  282. public static bool ReadBoolAttribute(XmlReader reader, out Exception innerExcpetion)
  283. {
  284. innerExcpetion = null;
  285. try
  286. {
  287. bool val = XmlConvert.ToBoolean(reader.Value);
  288. return val;
  289. }
  290. catch(Exception ex)
  291. {
  292. innerExcpetion = ex;
  293. return false;
  294. }
  295. }
  296. public static decimal ReadDecimalAttribute(XmlReader reader, out Exception innerExcpetion)
  297. {
  298. innerExcpetion = null;
  299. try
  300. {
  301. decimal val = XmlConvert.ToDecimal(reader.Value);
  302. return val;
  303. }
  304. catch(Exception ex)
  305. {
  306. innerExcpetion = ex;
  307. return decimal.Zero;
  308. }
  309. }
  310. // Is some value is read, return it.
  311. // If no values return empty.
  312. // If exception, return none
  313. public static XmlSchemaDerivationMethod ReadDerivationAttribute(XmlReader reader, out Exception innerExcpetion, string name, XmlSchemaDerivationMethod allowed)
  314. {
  315. innerExcpetion = null;
  316. try
  317. {
  318. string list = reader.Value;
  319. string warn = "";
  320. XmlSchemaDerivationMethod val = 0;
  321. if(list.IndexOf("#all") != -1 && list.Trim() != "#all")
  322. {
  323. innerExcpetion = new Exception(list+" is not a valid value for "+ name +". #all if present must be the only value");
  324. return XmlSchemaDerivationMethod.All;
  325. }
  326. foreach(string xsdm in XmlSchemaUtil.SplitList(list))
  327. {
  328. switch(xsdm)
  329. {
  330. case "":
  331. val = AddFlag (val, XmlSchemaDerivationMethod.Empty, allowed); break;
  332. case "#all":
  333. val = AddFlag (val,XmlSchemaDerivationMethod.All, allowed); break;
  334. case "substitution":
  335. val = AddFlag (val,XmlSchemaDerivationMethod.Substitution, allowed); break;
  336. case "extension":
  337. val = AddFlag (val,XmlSchemaDerivationMethod.Extension, allowed); break;
  338. case "restriction":
  339. val = AddFlag (val,XmlSchemaDerivationMethod.Restriction, allowed); break;
  340. case "list":
  341. val = AddFlag (val,XmlSchemaDerivationMethod.List, allowed); break;
  342. case "union":
  343. val = AddFlag (val,XmlSchemaDerivationMethod.Union, allowed); break;
  344. default:
  345. warn += xsdm + " "; break;
  346. }
  347. }
  348. if(warn != "")
  349. innerExcpetion = new Exception(warn + "is/are not valid values for " + name);
  350. return val;
  351. }
  352. catch(Exception ex)
  353. {
  354. innerExcpetion = ex;
  355. return XmlSchemaDerivationMethod.None;
  356. }
  357. }
  358. private static XmlSchemaDerivationMethod AddFlag (XmlSchemaDerivationMethod dst,
  359. XmlSchemaDerivationMethod add, XmlSchemaDerivationMethod allowed)
  360. {
  361. if ((add & allowed) == 0 && allowed != XmlSchemaDerivationMethod.All)
  362. throw new ArgumentException (add + " is not allowed in this attribute.");
  363. if ((dst & add) != 0)
  364. throw new ArgumentException (add + " is already specified in this attribute.");
  365. return dst | add;
  366. }
  367. public static XmlSchemaForm ReadFormAttribute(XmlReader reader, out Exception innerExcpetion)
  368. {
  369. innerExcpetion = null;
  370. XmlSchemaForm val = XmlSchemaForm.None;
  371. switch(reader.Value)
  372. {
  373. case "qualified":
  374. val = XmlSchemaForm.Qualified; break;
  375. case "unqualified":
  376. val = XmlSchemaForm.Unqualified; break;
  377. default:
  378. innerExcpetion = new Exception("only qualified or unqulified is a valid value"); break;
  379. }
  380. return val;
  381. }
  382. public static XmlSchemaContentProcessing ReadProcessingAttribute(XmlReader reader, out Exception innerExcpetion)
  383. {
  384. innerExcpetion = null;
  385. XmlSchemaContentProcessing val = XmlSchemaContentProcessing.None;
  386. switch(reader.Value)
  387. {
  388. case "lax":
  389. val = XmlSchemaContentProcessing.Lax; break;
  390. case "strict":
  391. val = XmlSchemaContentProcessing.Strict; break;
  392. case "skip":
  393. val = XmlSchemaContentProcessing.Skip; break;
  394. default:
  395. innerExcpetion = new Exception("only lax , strict or skip are valid values for processContents");
  396. break;
  397. }
  398. return val;
  399. }
  400. public static XmlSchemaUse ReadUseAttribute(XmlReader reader, out Exception innerExcpetion)
  401. {
  402. innerExcpetion = null;
  403. XmlSchemaUse val = XmlSchemaUse.None;
  404. switch(reader.Value)
  405. {
  406. case "optional":
  407. val = XmlSchemaUse.Optional; break;
  408. case "prohibited":
  409. val = XmlSchemaUse.Prohibited; break;
  410. case "required":
  411. val = XmlSchemaUse.Required; break;
  412. default:
  413. innerExcpetion = new Exception("only optional , prohibited or required are valid values for use");
  414. break;
  415. }
  416. return val;
  417. }
  418. public static XmlQualifiedName ReadQNameAttribute(XmlReader reader, out Exception innerEx)
  419. {
  420. return ToQName(reader, reader.Value, out innerEx);
  421. }
  422. //While Creating a XmlQualifedName, we should check:
  423. // 1. If a prefix is present, its namespace should be resolvable.
  424. // 2. If a prefix is not present, and if the defaultNamespace is set,
  425. public static XmlQualifiedName ToQName(XmlReader reader, string qnamestr, out Exception innerEx)
  426. {
  427. string ns;
  428. string name;
  429. XmlQualifiedName qname;
  430. innerEx = null;
  431. if(!IsValidQName(qnamestr))
  432. {
  433. innerEx = new Exception(qnamestr + " is an invalid QName. Either name or namespace is not a NCName");
  434. return XmlQualifiedName.Empty;
  435. }
  436. string[] values = qnamestr.Split(new char[]{':'},2);
  437. if(values.Length == 2)
  438. {
  439. ns = reader.LookupNamespace(values[0]);
  440. if(ns == null)
  441. {
  442. innerEx = new Exception("Namespace Prefix '"+values[0]+"could not be resolved");
  443. return XmlQualifiedName.Empty;
  444. }
  445. name = values[1];
  446. }
  447. else
  448. {
  449. //Default Namespace
  450. ns = reader.LookupNamespace("");
  451. name = values[0];
  452. }
  453. qname = new XmlQualifiedName(name,ns);
  454. return qname;
  455. }
  456. public static int ValidateAttributesResolved (
  457. XmlSchemaObjectTable attributesResolved,
  458. ValidationEventHandler h,
  459. XmlSchema schema,
  460. XmlSchemaObjectCollection attributes,
  461. XmlSchemaAnyAttribute anyAttribute,
  462. ref XmlSchemaAnyAttribute anyAttributeUse,
  463. XmlSchemaAttributeGroup redefined)
  464. {
  465. int errorCount = 0;
  466. if (anyAttribute != null && anyAttributeUse == null)
  467. anyAttributeUse = anyAttribute;
  468. foreach (XmlSchemaObject xsobj in attributes) {
  469. XmlSchemaAttributeGroupRef grpRef = xsobj as XmlSchemaAttributeGroupRef;
  470. if (grpRef != null) {
  471. // Resolve attributeGroup redefinition.
  472. XmlSchemaAttributeGroup grp = null;
  473. if (redefined != null && grpRef.RefName == redefined.QualifiedName)
  474. grp = redefined;
  475. else
  476. grp = schema.AttributeGroups [grpRef.RefName] as XmlSchemaAttributeGroup;
  477. // otherwise, it might be missing sub components.
  478. if (grp == null) {
  479. if (!schema.missedSubComponents)// && schema.Schemas [grpRef.RefName.Namespace] != null)
  480. grpRef.error (h, "Referenced attribute group " + grpRef.RefName + " was not found in the corresponding schema.");
  481. continue;
  482. }
  483. if (grp.AttributeGroupRecursionCheck) {
  484. grp.error (h, "Attribute group recursion was found: " + grpRef.RefName);
  485. continue;
  486. }
  487. try {
  488. grp.AttributeGroupRecursionCheck = true;
  489. errorCount += grp.Validate (h, schema);
  490. } finally {
  491. grp.AttributeGroupRecursionCheck = false;
  492. }
  493. if (grp.AnyAttributeUse != null) {
  494. if (anyAttribute == null)
  495. anyAttributeUse = grp.AnyAttributeUse;
  496. }
  497. foreach (DictionaryEntry entry in grp.AttributeUses) {
  498. XmlSchemaAttribute attr = (XmlSchemaAttribute) entry.Value;
  499. #if BUGGY_MS_COMPLIANT
  500. if (attr.Use == XmlSchemaUse.Prohibited)
  501. continue;
  502. #endif
  503. if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty)
  504. AddToTable (attributesResolved, attr, attr.RefName, h);
  505. else
  506. AddToTable (attributesResolved, attr, attr.QualifiedName, h);
  507. }
  508. } else {
  509. XmlSchemaAttribute attr = xsobj as XmlSchemaAttribute;
  510. if (attr != null) {
  511. errorCount += attr.Validate (h, schema);
  512. #if BUGGY_MS_COMPLIANT
  513. if (attr.Use == XmlSchemaUse.Prohibited)
  514. continue;
  515. #endif
  516. if (attr.RefName != null && attr.RefName != XmlQualifiedName.Empty)
  517. AddToTable (attributesResolved, attr, attr.RefName, h);
  518. else
  519. AddToTable (attributesResolved, attr, attr.QualifiedName, h);
  520. } else {
  521. if (anyAttribute == null) {
  522. anyAttributeUse = (XmlSchemaAnyAttribute) xsobj;
  523. anyAttribute.Validate (h, schema);
  524. }
  525. }
  526. }
  527. }
  528. return errorCount;
  529. }
  530. #if NET_2_0
  531. public static object ReadTypedValue (XmlReader reader,
  532. object type, IXmlNamespaceResolver nsResolver,
  533. StringBuilder tmpBuilder)
  534. #else
  535. public static object ReadTypedValue (XmlReader reader,
  536. object type, XmlNamespaceManager nsResolver,
  537. StringBuilder tmpBuilder)
  538. #endif
  539. {
  540. if (tmpBuilder == null)
  541. tmpBuilder = new StringBuilder ();
  542. XmlSchemaDatatype dt = type as XmlSchemaDatatype;
  543. XmlSchemaSimpleType st = type as XmlSchemaSimpleType;
  544. if (st != null)
  545. dt = st.Datatype;
  546. if (dt == null)
  547. return null;
  548. switch (reader.NodeType) {
  549. case XmlNodeType.Element:
  550. if (reader.IsEmptyElement)
  551. return null;
  552. tmpBuilder.Length = 0;
  553. bool loop = true;
  554. do {
  555. reader.Read ();
  556. switch (reader.NodeType) {
  557. case XmlNodeType.SignificantWhitespace:
  558. case XmlNodeType.Text:
  559. case XmlNodeType.CDATA:
  560. tmpBuilder.Append (reader.Value);
  561. break;
  562. case XmlNodeType.Comment:
  563. break;
  564. default:
  565. loop = false;
  566. break;
  567. }
  568. } while (loop && !reader.EOF && reader.ReadState == ReadState.Interactive);
  569. return dt.ParseValue (tmpBuilder.ToString (), reader.NameTable, nsResolver);
  570. case XmlNodeType.Attribute:
  571. return dt.ParseValue (reader.Value, reader.NameTable, nsResolver);
  572. }
  573. return null;
  574. }
  575. public static XmlSchemaObject FindAttributeDeclaration (
  576. string ns,
  577. XmlSchemaSet schemas,
  578. XmlSchemaComplexType cType,
  579. XmlQualifiedName qname)
  580. {
  581. XmlSchemaObject result = cType.AttributeUses [qname];
  582. if (result != null)
  583. return result;
  584. if (cType.AttributeWildcard == null)
  585. return null;
  586. if (!AttributeWildcardItemValid (cType.AttributeWildcard, qname, ns))
  587. return null;
  588. if (cType.AttributeWildcard.ResolvedProcessContents == XmlSchemaContentProcessing.Skip)
  589. return cType.AttributeWildcard;
  590. XmlSchemaAttribute attr = schemas.GlobalAttributes [qname] as XmlSchemaAttribute;
  591. if (attr != null)
  592. return attr;
  593. if (cType.AttributeWildcard.ResolvedProcessContents == XmlSchemaContentProcessing.Lax)
  594. return cType.AttributeWildcard;
  595. else
  596. return null;
  597. }
  598. // Spec 3.10.4 Item Valid (Wildcard)
  599. private static bool AttributeWildcardItemValid (XmlSchemaAnyAttribute anyAttr, XmlQualifiedName qname, string ns)
  600. {
  601. if (anyAttr.HasValueAny)
  602. return true;
  603. if (anyAttr.HasValueOther && (anyAttr.TargetNamespace == "" || ns != anyAttr.TargetNamespace))
  604. return true;
  605. if (anyAttr.HasValueTargetNamespace && ns == anyAttr.TargetNamespace)
  606. return true;
  607. if (anyAttr.HasValueLocal && ns == "")
  608. return true;
  609. for (int i = 0; i < anyAttr.ResolvedNamespaces.Count; i++)
  610. if (anyAttr.ResolvedNamespaces [i] == ns)
  611. return true;
  612. return false;
  613. }
  614. }
  615. }