XMLSchema.cs 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523
  1. //------------------------------------------------------------------------------
  2. // <copyright file="XMLSchema.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. namespace System.Data {
  9. using System;
  10. using System.Data.Common;
  11. using System.Xml;
  12. using System.Xml.Schema;
  13. using System.Diagnostics;
  14. using System.Collections;
  15. using System.Collections.Generic;
  16. using System.Globalization;
  17. using System.ComponentModel;
  18. using System.Security;
  19. using System.Security.Permissions;
  20. internal class XMLSchema {
  21. internal static TypeConverter GetConverter(Type type) {
  22. #if FEATURE_MONO_CAS
  23. HostProtectionAttribute protAttrib = new HostProtectionAttribute();
  24. protAttrib.SharedState = true;
  25. CodeAccessPermission permission = (CodeAccessPermission)protAttrib.CreatePermission();
  26. permission.Assert();
  27. #endif
  28. try {
  29. return TypeDescriptor.GetConverter(type);
  30. }
  31. finally {
  32. #if FEATURE_MONO_CAS
  33. CodeAccessPermission.RevertAssert();
  34. #endif
  35. }
  36. }
  37. internal static void SetProperties(Object instance, XmlAttributeCollection attrs) {
  38. // This is called from both XSD and XDR schemas.
  39. // Do we realy need it in XSD ???
  40. for (int i = 0; i < attrs.Count; i++) {
  41. if (attrs[i].NamespaceURI == Keywords.MSDNS) {
  42. string name = attrs[i].LocalName;
  43. string value = attrs[i].Value;
  44. if (name == "DefaultValue" || name == "RemotingFormat")
  45. continue;
  46. // Webdata 97925, skipp expressions, we will handle them after SetProperties (in xdrschema)
  47. if (name == "Expression" && instance is DataColumn)
  48. continue;
  49. PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name];
  50. if (pd != null) {
  51. // Standard property
  52. Type type = pd.PropertyType;
  53. TypeConverter converter = XMLSchema.GetConverter(type);
  54. object propValue;
  55. if (converter.CanConvertFrom(typeof(string))) {
  56. propValue = converter.ConvertFromString(value);
  57. }else if (type == typeof(Type)) {
  58. propValue = DataStorage.GetType(value);
  59. }else if (type == typeof(CultureInfo)) {
  60. propValue = new CultureInfo(value);
  61. }else {
  62. throw ExceptionBuilder.CannotConvert(value,type.FullName);
  63. }
  64. pd.SetValue(instance, propValue);
  65. }
  66. }
  67. }
  68. }// SetProperties
  69. internal static bool FEqualIdentity(XmlNode node, String name, String ns) {
  70. if (node != null && node.LocalName == name && node.NamespaceURI == ns)
  71. return true;
  72. return false;
  73. }
  74. internal static bool GetBooleanAttribute(XmlElement element, String attrName, String attrNS, bool defVal) {
  75. string value = element.GetAttribute(attrName, attrNS);
  76. if (value == null || value.Length == 0) {
  77. return defVal;
  78. }
  79. if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){
  80. return true;
  81. }
  82. if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){
  83. return false;
  84. }
  85. // Error processing:
  86. throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
  87. }
  88. internal static string GenUniqueColumnName(string proposedName, DataTable table) {
  89. if (table.Columns.IndexOf(proposedName) >= 0) {
  90. for (int i=0; i <= table.Columns.Count; i++) {
  91. string tempName = proposedName + "_" + (i).ToString(CultureInfo.InvariantCulture);
  92. if (table.Columns.IndexOf(tempName) >= 0) {
  93. continue;
  94. }
  95. else {
  96. return tempName;
  97. }
  98. }
  99. }
  100. return proposedName;
  101. }
  102. }
  103. internal sealed class ConstraintTable {
  104. public DataTable table;
  105. public XmlSchemaIdentityConstraint constraint;
  106. public ConstraintTable(DataTable t, XmlSchemaIdentityConstraint c) {
  107. table = t;
  108. constraint = c;
  109. }
  110. }
  111. internal sealed class XSDSchema : XMLSchema
  112. {
  113. XmlSchemaSet _schemaSet = null;
  114. XmlSchemaElement dsElement = null;
  115. DataSet _ds = null;
  116. String _schemaName = null;
  117. private ArrayList ColumnExpressions;
  118. private Hashtable ConstraintNodes;
  119. private ArrayList RefTables;
  120. private ArrayList complexTypes;
  121. XmlSchemaObjectCollection annotations;
  122. XmlSchemaObjectCollection elements;
  123. Hashtable attributes;
  124. Hashtable elementsTable;
  125. Hashtable attributeGroups;
  126. Hashtable schemaTypes;
  127. Hashtable expressions;
  128. Dictionary <DataTable, List<DataTable>> tableDictionary;
  129. Hashtable udSimpleTypes;
  130. Hashtable existingSimpleTypeMap;
  131. private bool fromInference = false;
  132. internal bool FromInference {
  133. get {
  134. return fromInference;
  135. }
  136. set {
  137. fromInference = value;
  138. }
  139. }
  140. private void CollectElementsAnnotations(XmlSchema schema){
  141. ArrayList schemaList = new ArrayList();
  142. CollectElementsAnnotations(schema, schemaList);
  143. schemaList.Clear();
  144. }
  145. private void CollectElementsAnnotations(XmlSchema schema, ArrayList schemaList){
  146. if (schemaList.Contains(schema)) {
  147. return;
  148. }
  149. schemaList.Add(schema);
  150. foreach(object item in schema.Items) {
  151. if (item is XmlSchemaAnnotation) {
  152. annotations.Add((XmlSchemaAnnotation)item);
  153. }
  154. if (item is XmlSchemaElement) {
  155. XmlSchemaElement elem = (XmlSchemaElement)item;
  156. elements.Add(elem);
  157. elementsTable[elem.QualifiedName] = elem;
  158. }
  159. if (item is XmlSchemaAttribute) {
  160. XmlSchemaAttribute attr = (XmlSchemaAttribute)item;
  161. attributes[attr.QualifiedName] = attr;
  162. }
  163. if (item is XmlSchemaAttributeGroup) {
  164. XmlSchemaAttributeGroup attr = (XmlSchemaAttributeGroup)item;
  165. attributeGroups[attr.QualifiedName] = attr;
  166. }
  167. if (item is XmlSchemaType) {
  168. string MSDATATargetNamespace = null;
  169. if (item is XmlSchemaSimpleType) {
  170. MSDATATargetNamespace = XSDSchema.GetMsdataAttribute((XmlSchemaType)item, Keywords.TARGETNAMESPACE);
  171. }
  172. XmlSchemaType type = (XmlSchemaType)item;
  173. schemaTypes[type.QualifiedName] = type;
  174. // Webdata 92054 if we have a User Defined simple type, cache it so later we may need for mapping
  175. // meanwhile more convinient solution would be to directly use schemaTypes, but it would be more complex to handle
  176. XmlSchemaSimpleType xmlSimpleType = (item as XmlSchemaSimpleType );
  177. if (xmlSimpleType != null) {
  178. if (udSimpleTypes == null) {
  179. udSimpleTypes = new Hashtable();
  180. }
  181. udSimpleTypes[type.QualifiedName.ToString()] = xmlSimpleType;
  182. DataColumn dc = (DataColumn)existingSimpleTypeMap[type.QualifiedName.ToString()];
  183. // Assumption is that our simple type qualified name ihas the same output as XmlSchemaSimpleType type.QualifiedName.ToString()
  184. SimpleType tmpSimpleType = (dc != null)? dc.SimpleType: null;
  185. //
  186. if (tmpSimpleType != null) {
  187. SimpleType tmpDataSimpleType = new SimpleType(xmlSimpleType);
  188. string errorStr = tmpSimpleType.HasConflictingDefinition(tmpDataSimpleType);
  189. if (errorStr.Length != 0) {
  190. throw ExceptionBuilder.InvalidDuplicateNamedSimpleTypeDelaration(tmpDataSimpleType.SimpleTypeQualifiedName, errorStr);
  191. }
  192. }
  193. }
  194. }
  195. }
  196. foreach(XmlSchemaExternal include in schema.Includes) {
  197. if (include is XmlSchemaImport)
  198. continue;
  199. if (include.Schema != null) {
  200. CollectElementsAnnotations(include.Schema, schemaList);
  201. }
  202. }
  203. }
  204. internal static string QualifiedName(string name) {
  205. int iStart = name.IndexOf(':');
  206. if (iStart == -1)
  207. return Keywords.XSD_PREFIXCOLON + name;
  208. else
  209. return name;
  210. }
  211. internal static void SetProperties(Object instance, XmlAttribute[] attrs) {
  212. // This is called from both XSD and XDR schemas.
  213. // Do we realy need it in XSD ???
  214. if (attrs == null)
  215. return;
  216. for (int i = 0; i < attrs.Length; i++) {
  217. if (attrs[i].NamespaceURI == Keywords.MSDNS) {
  218. string name = attrs[i].LocalName;
  219. string value = attrs[i].Value;
  220. if (name == "DefaultValue" || name == "Ordinal" || name == "Locale" || name == "RemotingFormat")
  221. continue;
  222. if (name == "Expression" && instance is DataColumn) // Webdata 97925: we will handle columnexpressions at HandleColumnExpression
  223. continue;
  224. if (name == "DataType") {
  225. DataColumn col = instance as DataColumn;
  226. if (col != null) {
  227. col.DataType = DataStorage.GetType(value);
  228. }
  229. continue;
  230. }
  231. PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name];
  232. if (pd != null) {
  233. // Standard property
  234. Type type = pd.PropertyType;
  235. TypeConverter converter = XMLSchema.GetConverter(type);
  236. object propValue;
  237. if (converter.CanConvertFrom(typeof(string))) {
  238. propValue = converter.ConvertFromString(value);
  239. }else if (type == typeof(Type)) {
  240. propValue = Type.GetType(value);
  241. }else if (type == typeof(CultureInfo)) {
  242. propValue = new CultureInfo(value);
  243. }else {
  244. throw ExceptionBuilder.CannotConvert(value,type.FullName);
  245. }
  246. pd.SetValue(instance, propValue);
  247. }
  248. }
  249. }
  250. }// SetProperties
  251. private static void SetExtProperties(Object instance, XmlAttribute[] attrs) {
  252. PropertyCollection props = null;
  253. if (attrs == null)
  254. return;
  255. for (int i = 0; i < attrs.Length; i++) {
  256. if (attrs[i].NamespaceURI == Keywords.MSPROPNS) {
  257. if(props == null) {
  258. object val = TypeDescriptor.GetProperties(instance)["ExtendedProperties"].GetValue(instance);
  259. Debug.Assert(val is PropertyCollection, "We can set values only for classes that have ExtendedProperties");
  260. props = (PropertyCollection) val;
  261. }
  262. string propName = XmlConvert.DecodeName(attrs[i].LocalName);
  263. if (instance is ForeignKeyConstraint) {
  264. if (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal))
  265. propName = propName.Substring(3);
  266. else
  267. continue;
  268. }
  269. if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_REL_PREFIX, StringComparison.Ordinal))) {
  270. propName = propName.Substring(4);
  271. }
  272. else if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal))) {
  273. continue;
  274. }
  275. props.Add(propName, attrs[i].Value);
  276. }
  277. }
  278. }// SetExtProperties
  279. private void HandleColumnExpression(Object instance, XmlAttribute[] attrs) {
  280. if (attrs == null)
  281. return;
  282. DataColumn dc = instance as DataColumn;
  283. Debug.Assert(dc != null, "HandleColumnExpression is supposed to be called for DataColumn");
  284. if (dc != null ) {
  285. for (int i = 0; i < attrs.Length; i++) {
  286. if (attrs[i].NamespaceURI == Keywords.MSDNS) {
  287. if (attrs[i].LocalName == "Expression"){
  288. if (this.expressions == null)
  289. this.expressions = new Hashtable();
  290. this.expressions[dc] = attrs[i].Value;
  291. ColumnExpressions.Add(dc);
  292. break;
  293. }
  294. }
  295. }
  296. }
  297. }
  298. internal static String GetMsdataAttribute(XmlSchemaAnnotated node, String ln) {
  299. XmlAttribute[] nodeAttributes = node.UnhandledAttributes;
  300. if (nodeAttributes!=null)
  301. for(int i=0; i<nodeAttributes.Length;i++)
  302. if (nodeAttributes[i].LocalName == ln && nodeAttributes[i].NamespaceURI == Keywords.MSDNS)
  303. return nodeAttributes[i].Value;
  304. return null;
  305. }
  306. private static void SetExtProperties(Object instance, XmlAttributeCollection attrs) {
  307. PropertyCollection props = null;
  308. for (int i = 0; i < attrs.Count; i++) {
  309. if (attrs[i].NamespaceURI == Keywords.MSPROPNS) {
  310. if(props == null) {
  311. object val = TypeDescriptor.GetProperties(instance)["ExtendedProperties"].GetValue(instance);
  312. Debug.Assert(val is PropertyCollection, "We can set values only for classes that have ExtendedProperties");
  313. props = (PropertyCollection) val;
  314. }
  315. string propName = XmlConvert.DecodeName(attrs[i].LocalName);
  316. props.Add(propName, attrs[i].Value);
  317. }
  318. }
  319. }// SetExtProperties
  320. internal void HandleRefTableProperties(ArrayList RefTables, XmlSchemaElement element) {
  321. string typeName = GetInstanceName(element);
  322. DataTable table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), element.QualifiedName.Namespace);
  323. Debug.Assert(table != null, "ref table should have been already created");
  324. SetProperties(table, element.UnhandledAttributes);
  325. SetExtProperties(table, element.UnhandledAttributes);
  326. }
  327. internal void HandleRelation(XmlElement node, bool fNested) {
  328. string strName;
  329. string parentName;
  330. string childName;
  331. string [] parentNames;
  332. string [] childNames;
  333. string value;
  334. bool fCreateConstraints = false; //if we have a relation,
  335. //we do not have constraints
  336. DataRelationCollection rels = _ds.Relations;
  337. DataRelation relation;
  338. DataColumn [] parentKey;
  339. DataColumn [] childKey;
  340. DataTable parent;
  341. DataTable child;
  342. int keyLength;
  343. strName = XmlConvert.DecodeName(node.GetAttribute(Keywords.NAME));
  344. for (int i = 0; i < rels.Count; ++i) {
  345. if (0 == String.Compare(rels[i].RelationName, strName, StringComparison.Ordinal))
  346. return;
  347. }
  348. parentName = node.GetAttribute(Keywords.MSD_PARENT, Keywords.MSDNS);
  349. if (parentName == null || parentName.Length==0)
  350. throw ExceptionBuilder.RelationParentNameMissing(strName);
  351. parentName = XmlConvert.DecodeName(parentName);
  352. childName = node.GetAttribute(Keywords.MSD_CHILD, Keywords.MSDNS);
  353. if (childName == null || childName.Length==0)
  354. throw ExceptionBuilder.RelationChildNameMissing(strName);
  355. childName = XmlConvert.DecodeName(childName);
  356. value = node.GetAttribute(Keywords.MSD_PARENTKEY, Keywords.MSDNS);
  357. if (value == null || value.Length==0)
  358. throw ExceptionBuilder.RelationTableKeyMissing(strName);
  359. parentNames = value.TrimEnd(null).Split(new char[] {Keywords.MSD_KEYFIELDSEP, Keywords.MSD_KEYFIELDOLDSEP});
  360. value = node.GetAttribute(Keywords.MSD_CHILDKEY, Keywords.MSDNS);
  361. if (value == null || value.Length==0)
  362. throw ExceptionBuilder.RelationChildKeyMissing(strName);
  363. childNames = value.TrimEnd(null).Split(new char[] {Keywords.MSD_KEYFIELDSEP, Keywords.MSD_KEYFIELDOLDSEP});
  364. keyLength = parentNames.Length;
  365. if (keyLength != childNames.Length)
  366. throw ExceptionBuilder.MismatchKeyLength();
  367. parentKey = new DataColumn[keyLength];
  368. childKey = new DataColumn[keyLength];
  369. string parentNs = node.GetAttribute(Keywords.MSD_PARENTTABLENS, Keywords.MSDNS);
  370. string childNs = node.GetAttribute(Keywords.MSD_CHILDTABLENS, Keywords.MSDNS);
  371. parent = _ds.Tables.GetTableSmart(parentName,parentNs);
  372. if (parent == null)
  373. throw ExceptionBuilder.ElementTypeNotFound(parentName);
  374. child = _ds.Tables.GetTableSmart(childName,childNs);
  375. if (child == null)
  376. throw ExceptionBuilder.ElementTypeNotFound(childName);
  377. for (int i = 0; i < keyLength; i++) {
  378. parentKey[i] = parent.Columns[XmlConvert.DecodeName(parentNames[i])];
  379. if (parentKey[i] == null)
  380. throw ExceptionBuilder.ElementTypeNotFound(parentNames[i]);
  381. childKey[i] = child.Columns[XmlConvert.DecodeName(childNames[i])];
  382. if (childKey[i] == null)
  383. throw ExceptionBuilder.ElementTypeNotFound(childNames[i]);
  384. }
  385. relation = new DataRelation(strName, parentKey, childKey, fCreateConstraints);
  386. relation.Nested = fNested;
  387. SetExtProperties(relation, node.Attributes);
  388. _ds.Relations.Add(relation);
  389. if (FromInference && relation.Nested) {
  390. tableDictionary[relation.ParentTable].Add(relation.ChildTable);
  391. }
  392. }
  393. private bool HasAttributes(XmlSchemaObjectCollection attributes){
  394. foreach (XmlSchemaObject so in attributes) {
  395. if (so is XmlSchemaAttribute) {
  396. return true;
  397. }
  398. if (so is XmlSchemaAttributeGroup) {
  399. return true;
  400. }
  401. if (so is XmlSchemaAttributeGroupRef) {
  402. return true;
  403. }
  404. }
  405. return false;
  406. }
  407. private bool IsDatasetParticle(XmlSchemaParticle pt){
  408. XmlSchemaObjectCollection items = GetParticleItems(pt);
  409. if (items == null)
  410. return false; // empty element, threat it as table
  411. bool isChoice = this.FromInference && (pt is XmlSchemaChoice);// currently we add this support for choice, just for inference
  412. foreach (XmlSchemaAnnotated el in items){
  413. if (el is XmlSchemaElement) {
  414. // pushing max occur of choice element to its imidiate children of type xs:elements
  415. if (isChoice && pt.MaxOccurs > Decimal.One && (((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) // we know frominference condition
  416. ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
  417. if (((XmlSchemaElement)el).RefName.Name.Length != 0) {
  418. if (!FromInference || (((XmlSchemaElement)el).MaxOccurs != Decimal.One && !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)))
  419. continue;
  420. }
  421. if (!IsTable ((XmlSchemaElement)el))
  422. return false;
  423. continue;
  424. }
  425. if (el is XmlSchemaParticle) {
  426. if (!IsDatasetParticle((XmlSchemaParticle)el))
  427. return false;
  428. }
  429. }
  430. return true;
  431. }
  432. private int DatasetElementCount(XmlSchemaObjectCollection elements) {
  433. int nCount = 0;
  434. foreach(XmlSchemaElement XmlElement in elements) {
  435. if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET, /*default:*/ false)) {
  436. nCount++;
  437. }
  438. }
  439. return nCount;
  440. }
  441. private XmlSchemaElement FindDatasetElement(XmlSchemaObjectCollection elements) {
  442. foreach(XmlSchemaElement XmlElement in elements) {
  443. if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET, /*default:*/ false))
  444. return XmlElement;
  445. }
  446. if ((elements.Count == 1) || (this.FromInference && elements.Count > 0)) { //let's see if this element looks like a DataSet
  447. XmlSchemaElement node = (XmlSchemaElement)elements[0];
  448. if (!GetBooleanAttribute(node, Keywords.MSD_ISDATASET, /*default:*/ true))
  449. return null;
  450. XmlSchemaComplexType ct = node.SchemaType as XmlSchemaComplexType;
  451. if (ct == null)
  452. return null;
  453. while (ct != null) {
  454. if (HasAttributes(ct.Attributes))
  455. return null;
  456. if (ct.ContentModel is XmlSchemaSimpleContent){
  457. XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content;
  458. if (cContent is XmlSchemaSimpleContentExtension) {
  459. XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent );
  460. if (HasAttributes(ccExtension.Attributes))
  461. return null;
  462. } else {
  463. XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent );
  464. if (HasAttributes(ccRestriction.Attributes))
  465. return null;
  466. }
  467. }
  468. XmlSchemaParticle particle = GetParticle(ct);
  469. if (particle != null) {
  470. if (!IsDatasetParticle(particle))
  471. return null; // it's a table
  472. }
  473. if (ct.BaseXmlSchemaType is XmlSchemaComplexType)
  474. ct = (XmlSchemaComplexType)ct.BaseXmlSchemaType;
  475. else
  476. break;
  477. }
  478. //if we are here there all elements are tables
  479. return node;
  480. }
  481. return null;
  482. }
  483. public void LoadSchema(XmlSchemaSet schemaSet , DataTable dt) {
  484. if (dt.DataSet != null)
  485. LoadSchema(schemaSet, dt.DataSet);
  486. }
  487. public void LoadSchema(XmlSchemaSet schemaSet , DataSet ds) { //Element schemaRoot, DataSet ds) {
  488. ConstraintNodes = new Hashtable();
  489. RefTables = new ArrayList();
  490. ColumnExpressions = new ArrayList();
  491. complexTypes = new ArrayList();
  492. bool setRootNStoDataSet = false;
  493. bool newDataSet = (ds.Tables.Count == 0);
  494. if (schemaSet == null) //
  495. return;
  496. _schemaSet = schemaSet;
  497. _ds = ds;
  498. ds.fIsSchemaLoading = true;
  499. foreach (XmlSchema schemaRoot in schemaSet.Schemas()) {
  500. _schemaName = schemaRoot.Id;
  501. if (_schemaName == null ||_schemaName.Length == 0) {
  502. _schemaName = "NewDataSet";
  503. }
  504. ds.DataSetName = XmlConvert.DecodeName(_schemaName);
  505. string ns = schemaRoot.TargetNamespace;
  506. if (ds.namespaceURI == null || ds.namespaceURI.Length == 0) {// set just one time, for backward compatibility
  507. ds.namespaceURI = (ns== null)? string.Empty : ns; // see fx\Data\XDO\ReadXml\SchemaM2.xml for more info
  508. }
  509. break; // we just need to take Name and NS from first schema [V1.0 & v1.1 semantics]
  510. }
  511. annotations = new XmlSchemaObjectCollection();
  512. elements = new XmlSchemaObjectCollection();
  513. elementsTable = new Hashtable();
  514. attributes = new Hashtable();
  515. attributeGroups = new Hashtable();
  516. schemaTypes = new Hashtable();
  517. tableDictionary = new Dictionary <DataTable, List<DataTable>>() ;
  518. existingSimpleTypeMap = new Hashtable();
  519. foreach(DataTable dt in ds.Tables){
  520. foreach(DataColumn dc in dt.Columns) {
  521. if (dc.SimpleType!= null && dc.SimpleType.Name != null && dc.SimpleType.Name.Length != 0) {
  522. existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc;
  523. // existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc.SimpleType;
  524. }
  525. }
  526. }
  527. foreach (XmlSchema schemaRoot in schemaSet.Schemas())
  528. CollectElementsAnnotations(schemaRoot);
  529. dsElement = FindDatasetElement(elements);
  530. if (dsElement != null) {
  531. string mainName = GetStringAttribute (dsElement, Keywords.MSD_MAINDATATABLE, "");
  532. if (null != mainName) {
  533. ds.MainTableName = XmlConvert.DecodeName (mainName);
  534. }
  535. }
  536. else {
  537. if (this.FromInference) {
  538. ds.fTopLevelTable = true; // Backward compatability: for inference, if we do not read DataSet element
  539. }
  540. // we should not write it also
  541. setRootNStoDataSet = true;
  542. //incase of Root is not mapped to DataSet and is mapped to DataTable instead; to be backward compatable
  543. // we need to set the Namespace of Root to DataSet's namespace also(it would be NS of First DataTable in collection)
  544. }
  545. List<XmlQualifiedName> qnames = new List<XmlQualifiedName>();
  546. if (ds != null && ds.UseDataSetSchemaOnly) {
  547. int dataSetElementCount = DatasetElementCount(elements);
  548. if (dataSetElementCount == 0) {
  549. throw ExceptionBuilder.IsDataSetAttributeMissingInSchema();
  550. }
  551. else if (dataSetElementCount > 1) {
  552. throw ExceptionBuilder.TooManyIsDataSetAtributeInSchema();
  553. }
  554. XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(dsElement);
  555. if (ct.Particle != null) {
  556. XmlSchemaObjectCollection items = GetParticleItems(ct.Particle);
  557. if (items != null) {
  558. foreach (XmlSchemaAnnotated el in items){
  559. XmlSchemaElement sel = el as XmlSchemaElement;
  560. if (null != sel) {
  561. if(sel.RefName.Name.Length != 0 ) {
  562. qnames.Add(sel.QualifiedName);
  563. }
  564. }
  565. }
  566. }
  567. }
  568. }
  569. // Walk all the top level Element tags.
  570. foreach (XmlSchemaElement element in elements) {
  571. if (element == dsElement)
  572. continue;
  573. if (ds != null && ds.UseDataSetSchemaOnly && dsElement != null) {
  574. if (dsElement.Parent != element.Parent) {
  575. if (!qnames.Contains(element.QualifiedName)) {
  576. continue;
  577. }
  578. }
  579. }
  580. String typeName = GetInstanceName(element);
  581. if (RefTables.Contains(element.QualifiedName.Namespace +":"+ typeName)) {
  582. HandleRefTableProperties(RefTables, element);
  583. continue;
  584. }
  585. DataTable table = HandleTable(element);
  586. }
  587. if (dsElement!=null)
  588. HandleDataSet(dsElement, newDataSet);
  589. foreach (XmlSchemaAnnotation annotation in annotations) {
  590. HandleRelations(annotation, false);
  591. }
  592. //just add Expressions, at this point and if ColumnExpressions.Count > 0, this.expressions should not be null
  593. for(int i=0; i<ColumnExpressions.Count; i++) {
  594. DataColumn dc = ((DataColumn)(ColumnExpressions[i]));
  595. dc.Expression = (string) this.expressions[dc];
  596. }
  597. foreach (DataTable dt in ds.Tables) {
  598. if (dt.NestedParentRelations.Length == 0 && dt.Namespace == ds.Namespace) {
  599. DataRelationCollection childRelations = dt.ChildRelations;// WebData 113251 if we nulling NS of parent table,
  600. for (int j = 0; j < childRelations.Count; j++) { // we need to do the same thing for nested child tables as they
  601. if (childRelations[j].Nested && dt.Namespace == childRelations[j].ChildTable.Namespace) { // take NS from Parent table
  602. childRelations[j].ChildTable.tableNamespace = null;
  603. }
  604. }
  605. dt.tableNamespace = null;
  606. }
  607. }
  608. DataTable tmpTable = ds.Tables[ds.DataSetName, ds.Namespace];
  609. if ( tmpTable != null) // this fix is done to support round-trip problem in case if there is one table with same name and NS
  610. tmpTable.fNestedInDataset = true;
  611. // this fix is for backward compatability with old inference engine
  612. if (this.FromInference && ds.Tables.Count == 0 && String.Compare(ds.DataSetName, "NewDataSet", StringComparison.Ordinal) == 0)
  613. ds.DataSetName = XmlConvert.DecodeName(((XmlSchemaElement)elements[0]).Name);
  614. ds.fIsSchemaLoading = false; //reactivate column computations
  615. //for backward compatability; we need to set NS of Root Element to DataSet, if root already does not mapped to dataSet
  616. if (setRootNStoDataSet) {
  617. if (ds.Tables.Count > 0) { // if there is table, take first one's NS
  618. ds.Namespace = ds.Tables[0].Namespace;
  619. ds.Prefix = ds.Tables[0].Prefix;
  620. }
  621. else {// otherwise, take TargetNS from first schema
  622. Debug.Assert(schemaSet.Count == 1, "there should be one schema");
  623. foreach (XmlSchema schemaRoot in schemaSet.Schemas()) { // we should have 1 schema
  624. ds.Namespace = schemaRoot.TargetNamespace;
  625. }
  626. }
  627. }
  628. }
  629. private void HandleRelations(XmlSchemaAnnotation ann, bool fNested) {
  630. foreach (object __items in ann.Items)
  631. if (__items is XmlSchemaAppInfo) {
  632. XmlNode[] relations = ((XmlSchemaAppInfo) __items).Markup;
  633. for (int i = 0; i<relations.Length; i++)
  634. if (FEqualIdentity(relations[i], Keywords.MSD_RELATION, Keywords.MSDNS))
  635. HandleRelation((XmlElement)relations[i], fNested);
  636. }
  637. }
  638. internal XmlSchemaObjectCollection GetParticleItems(XmlSchemaParticle pt){
  639. if (pt is XmlSchemaSequence)
  640. return ((XmlSchemaSequence)pt).Items;
  641. if (pt is XmlSchemaAll)
  642. return ((XmlSchemaAll)pt).Items;
  643. if (pt is XmlSchemaChoice)
  644. return ((XmlSchemaChoice)pt).Items;
  645. if (pt is XmlSchemaAny)
  646. return null;
  647. // the code below is a little hack for the SOM behavior
  648. if (pt is XmlSchemaElement) {
  649. XmlSchemaObjectCollection Items = new XmlSchemaObjectCollection();
  650. Items.Add(pt);
  651. return Items;
  652. }
  653. if (pt is XmlSchemaGroupRef)
  654. return GetParticleItems( ((XmlSchemaGroupRef)pt).Particle );
  655. // should never get here.
  656. return null;
  657. }
  658. internal void HandleParticle(XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, bool isBase){
  659. XmlSchemaObjectCollection items = GetParticleItems(pt);
  660. if (items == null)
  661. return;
  662. foreach (XmlSchemaAnnotated item in items){
  663. XmlSchemaElement el = item as XmlSchemaElement;
  664. if (el != null) {
  665. if (this.FromInference && pt is XmlSchemaChoice && pt.MaxOccurs > Decimal.One && (el.SchemaType is XmlSchemaComplexType))
  666. ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
  667. DataTable child = null;
  668. // to decide if element is our table, we need to match both name and ns
  669. // 286043 - SQL BU Defect Tracking
  670. if (((el.Name == null) && (el.RefName.Name == table.EncodedTableName && el.RefName.Namespace == table.Namespace)) ||
  671. (IsTable(el) && el.Name == table.TableName)) {
  672. if (this.FromInference) {
  673. child = HandleTable ((XmlSchemaElement)el);
  674. Debug.Assert(child == table, "table not the same");
  675. }
  676. else {
  677. child = table;
  678. }
  679. }
  680. else {
  681. child = HandleTable ((XmlSchemaElement)el);
  682. if (child == null && this.FromInference && el.Name == table.TableName) {
  683. child = table;
  684. }
  685. }
  686. if (child==null) {
  687. if (!this.FromInference || el.Name != table.TableName) {// check is required to support 1.1 inference behavior
  688. HandleElementColumn((XmlSchemaElement)el, table, isBase);
  689. }
  690. }
  691. else {
  692. DataRelation relation = null;
  693. if (el.Annotation != null)
  694. HandleRelations(el.Annotation, true);
  695. DataRelationCollection childRelations = table.ChildRelations;
  696. for (int j = 0; j < childRelations.Count; j++) {
  697. if (!childRelations[j].Nested)
  698. continue;
  699. if (child == childRelations[j].ChildTable)
  700. relation = childRelations[j];
  701. }
  702. if (relation == null) {
  703. tableChildren.Add(child);// how about prefix for this?
  704. if(this.FromInference && table.UKColumnPositionForInference == -1) { // this is done for Inference
  705. int ukColumnPosition = -1;
  706. foreach(DataColumn dc in table.Columns) {
  707. if (dc.ColumnMapping == MappingType.Element)
  708. ukColumnPosition++;
  709. }
  710. table.UKColumnPositionForInference = ukColumnPosition + 1; // since it starts from
  711. }
  712. }
  713. }
  714. }
  715. else {
  716. HandleParticle((XmlSchemaParticle)item, table, tableChildren, isBase);
  717. }
  718. }
  719. return ;
  720. }
  721. internal void HandleAttributes(XmlSchemaObjectCollection attributes, DataTable table, bool isBase) {
  722. foreach (XmlSchemaObject so in attributes) {
  723. if (so is XmlSchemaAttribute) {
  724. HandleAttributeColumn((XmlSchemaAttribute) so, table, isBase);
  725. }
  726. else { // XmlSchemaAttributeGroupRef
  727. XmlSchemaAttributeGroupRef groupRef = so as XmlSchemaAttributeGroupRef;
  728. XmlSchemaAttributeGroup schemaGroup = attributeGroups[groupRef.RefName] as XmlSchemaAttributeGroup;
  729. if (schemaGroup!=null) {
  730. HandleAttributeGroup(schemaGroup, table, isBase);
  731. }
  732. }
  733. }
  734. }
  735. private void HandleAttributeGroup(XmlSchemaAttributeGroup attributeGroup, DataTable table, bool isBase) {
  736. foreach (XmlSchemaObject obj in attributeGroup.Attributes) {
  737. if (obj is XmlSchemaAttribute) {
  738. HandleAttributeColumn((XmlSchemaAttribute) obj, table, isBase);
  739. }
  740. else { // XmlSchemaAttributeGroupRef
  741. XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
  742. XmlSchemaAttributeGroup attributeGroupResolved;
  743. if (attributeGroup.RedefinedAttributeGroup != null && attributeGroupRef.RefName == new XmlQualifiedName(attributeGroup.Name, attributeGroupRef.RefName.Namespace)) {
  744. attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroup.RedefinedAttributeGroup;
  745. }
  746. else {
  747. attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroups[attributeGroupRef.RefName];
  748. }
  749. if (attributeGroupResolved != null) {
  750. HandleAttributeGroup(attributeGroupResolved, table, isBase);
  751. }
  752. }
  753. }
  754. }
  755. internal void HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, bool isNillable){
  756. if (complexTypes.Contains(ct))
  757. throw ExceptionBuilder.CircularComplexType(ct.Name);
  758. bool isBase = false;
  759. complexTypes.Add(ct);
  760. if (ct.ContentModel != null) {
  761. /*
  762. HandleParticle(ct.CompiledParticle, table, tableChildren, isBase);
  763. foreach (XmlSchemaAttribute s in ct.Attributes){
  764. HandleAttributeColumn(s, table, isBase);
  765. }
  766. */
  767. if (ct.ContentModel is XmlSchemaComplexContent) {
  768. XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
  769. if (cContent is XmlSchemaComplexContentExtension) {
  770. XmlSchemaComplexContentExtension ccExtension = ((XmlSchemaComplexContentExtension) cContent );
  771. if (!(ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference))
  772. HandleAttributes(ccExtension.Attributes, table, isBase);
  773. if (ct.BaseXmlSchemaType is XmlSchemaComplexType) {
  774. HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable);
  775. }
  776. else {
  777. Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType, "Expected SimpleType or ComplexType");
  778. if (ccExtension.BaseTypeName.Namespace != Keywords.XSDNS){
  779. // this is UDSimpleType, pass Qualified name of type
  780. HandleSimpleContentColumn(ccExtension.BaseTypeName.ToString(), table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
  781. }
  782. else { // it is built in type
  783. HandleSimpleContentColumn(ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
  784. }
  785. }
  786. if (ccExtension.Particle != null)
  787. HandleParticle(ccExtension.Particle, table, tableChildren, isBase);
  788. if (ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference)
  789. HandleAttributes(ccExtension.Attributes, table, isBase);
  790. } else {
  791. Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction");
  792. XmlSchemaComplexContentRestriction ccRestriction = ((XmlSchemaComplexContentRestriction) cContent );
  793. if (!this.FromInference)
  794. HandleAttributes(ccRestriction.Attributes, table, isBase);
  795. if (ccRestriction.Particle != null)
  796. HandleParticle(ccRestriction.Particle, table, tableChildren, isBase);
  797. if (this.FromInference)
  798. HandleAttributes(ccRestriction.Attributes, table, isBase);
  799. }
  800. } else {
  801. Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent");
  802. XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content;
  803. if (cContent is XmlSchemaSimpleContentExtension) {
  804. XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent );
  805. HandleAttributes(ccExtension.Attributes, table, isBase);
  806. if (ct.BaseXmlSchemaType is XmlSchemaComplexType) {
  807. HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable);
  808. }
  809. else {
  810. Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType, "Expected SimpleType or ComplexType");
  811. HandleSimpleTypeSimpleContentColumn((XmlSchemaSimpleType)ct.BaseXmlSchemaType, ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
  812. }
  813. } else {
  814. Debug.Assert(cContent is XmlSchemaSimpleContentRestriction, "Expected SimpleContent extension or restriction");
  815. XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent );
  816. HandleAttributes(ccRestriction.Attributes, table, isBase);
  817. }
  818. }
  819. }
  820. else {
  821. isBase = true;
  822. if (!this.FromInference)
  823. HandleAttributes(ct.Attributes, table, isBase);
  824. if (ct.Particle != null)
  825. HandleParticle(ct.Particle, table, tableChildren, isBase);
  826. if (this.FromInference) {
  827. HandleAttributes(ct.Attributes, table, isBase);
  828. if (isNillable) // this is for backward compatability to support xsi:Nill=true
  829. HandleSimpleContentColumn("string", table, isBase, null, isNillable);
  830. }
  831. }
  832. complexTypes.Remove(ct);
  833. }
  834. internal XmlSchemaParticle GetParticle(XmlSchemaComplexType ct){
  835. if (ct.ContentModel != null) {
  836. if (ct.ContentModel is XmlSchemaComplexContent) {
  837. XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
  838. if (cContent is XmlSchemaComplexContentExtension) {
  839. return ((XmlSchemaComplexContentExtension) cContent ).Particle;
  840. } else {
  841. Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction");
  842. return ((XmlSchemaComplexContentRestriction) cContent ).Particle;
  843. }
  844. } else {
  845. Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent");
  846. return null;
  847. }
  848. }
  849. else {
  850. return ct.Particle;
  851. }
  852. }
  853. internal DataColumn FindField(DataTable table, string field) {
  854. bool attribute = false;
  855. String colName = field;
  856. if (field.StartsWith("@", StringComparison.Ordinal)) {
  857. attribute = true;
  858. colName = field.Substring(1);
  859. }
  860. String [] split = colName.Split(':');
  861. colName = split [split.Length - 1];
  862. colName = XmlConvert.DecodeName(colName);
  863. DataColumn col = table.Columns[colName];
  864. if (col == null )
  865. throw ExceptionBuilder.InvalidField(field);
  866. bool _attribute = (col.ColumnMapping == MappingType.Attribute) || (col.ColumnMapping == MappingType.Hidden);
  867. if (_attribute != attribute)
  868. throw ExceptionBuilder.InvalidField(field);
  869. return col;
  870. }
  871. internal DataColumn[] BuildKey(XmlSchemaIdentityConstraint keyNode, DataTable table){
  872. ArrayList keyColumns = new ArrayList();
  873. foreach (XmlSchemaXPath node in keyNode.Fields) {
  874. keyColumns.Add(FindField(table, node.XPath));
  875. }
  876. DataColumn [] key = new DataColumn[keyColumns.Count];
  877. keyColumns.CopyTo(key, 0);
  878. return key;
  879. }
  880. internal bool GetBooleanAttribute(XmlSchemaAnnotated element, String attrName, bool defVal) {
  881. string value = GetMsdataAttribute(element, attrName);
  882. if (value == null || value.Length == 0) {
  883. return defVal;
  884. }
  885. if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){
  886. return true;
  887. }
  888. if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){
  889. return false;
  890. }
  891. // Error processing:
  892. throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
  893. }
  894. internal String GetStringAttribute(XmlSchemaAnnotated element, String attrName, String defVal) {
  895. string value = GetMsdataAttribute(element, attrName);
  896. if (value == null || value.Length == 0) {
  897. return defVal;
  898. }
  899. return value;
  900. }
  901. /*
  902. <key name="fk">
  903. <selector>../Customers</selector>
  904. <field>ID</field>
  905. </key>
  906. <keyref refer="fk">
  907. <selector>.</selector>
  908. <field>CustID</field>
  909. </keyref>
  910. */
  911. internal static AcceptRejectRule TranslateAcceptRejectRule( string strRule ) {
  912. if (strRule == "Cascade")
  913. return AcceptRejectRule.Cascade;
  914. else if (strRule == "None")
  915. return AcceptRejectRule.None;
  916. else
  917. return ForeignKeyConstraint.AcceptRejectRule_Default;
  918. }
  919. internal static Rule TranslateRule( string strRule ) {
  920. if (strRule == "Cascade")
  921. return Rule.Cascade;
  922. else if (strRule == "None")
  923. return Rule.None;
  924. else if (strRule == "SetDefault")
  925. return Rule.SetDefault;
  926. else if (strRule == "SetNull")
  927. return Rule.SetNull;
  928. else
  929. return ForeignKeyConstraint.Rule_Default;
  930. }
  931. internal void HandleKeyref(XmlSchemaKeyref keyref) {
  932. string refer = XmlConvert.DecodeName(keyref.Refer.Name); // check here!!!
  933. string name = XmlConvert.DecodeName(keyref.Name);
  934. name = GetStringAttribute( keyref, "ConstraintName", /*default:*/ name);
  935. // we do not process key defined outside the current node
  936. String tableName = GetTableName(keyref);
  937. string tableNs = GetMsdataAttribute(keyref,Keywords.MSD_TABLENS);
  938. DataTable table = _ds.Tables.GetTableSmart(tableName,tableNs);
  939. if (table == null)
  940. return;
  941. if (refer == null || refer.Length == 0)
  942. throw ExceptionBuilder.MissingRefer(name);
  943. ConstraintTable key = (ConstraintTable) ConstraintNodes[refer];
  944. if (key == null) {
  945. throw ExceptionBuilder.InvalidKey(name);
  946. }
  947. DataColumn[] pKey = BuildKey(key.constraint, key.table);
  948. DataColumn[] fKey = BuildKey(keyref, table);
  949. ForeignKeyConstraint fkc = null;
  950. if (GetBooleanAttribute(keyref, Keywords.MSD_CONSTRAINTONLY, /*default:*/ false)) {
  951. int iExisting = fKey[0].Table.Constraints.InternalIndexOf(name);
  952. if (iExisting > -1) {
  953. if (fKey[0].Table.Constraints[iExisting].ConstraintName != name)
  954. iExisting = -1;
  955. }
  956. if (iExisting < 0) {
  957. fkc = new ForeignKeyConstraint( name, pKey, fKey );
  958. fKey[0].Table.Constraints.Add(fkc);
  959. }
  960. }
  961. else {
  962. string relName = XmlConvert.DecodeName(GetStringAttribute( keyref, Keywords.MSD_RELATIONNAME, keyref.Name));
  963. if (relName == null || relName.Length == 0)
  964. relName = name;
  965. int iExisting = fKey[0].Table.DataSet.Relations.InternalIndexOf(relName);
  966. if (iExisting > -1) {
  967. if (fKey[0].Table.DataSet.Relations[iExisting].RelationName != relName)
  968. iExisting = -1;
  969. }
  970. DataRelation relation = null;
  971. if (iExisting < 0) {
  972. relation = new DataRelation(relName, pKey, fKey);
  973. SetExtProperties(relation, keyref.UnhandledAttributes);
  974. pKey[0].Table.DataSet.Relations.Add(relation);
  975. if (FromInference && relation.Nested) {
  976. if (tableDictionary.ContainsKey(relation.ParentTable)) {
  977. tableDictionary[relation.ParentTable].Add(relation.ChildTable);
  978. }
  979. }
  980. fkc = relation.ChildKeyConstraint;
  981. fkc.ConstraintName = name;
  982. }
  983. else {
  984. relation = fKey[0].Table.DataSet.Relations[iExisting];
  985. }
  986. if (GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED, /*default:*/ false)) {
  987. relation.Nested = true;
  988. }
  989. }
  990. string acceptRejectRule = GetMsdataAttribute(keyref, Keywords.MSD_ACCEPTREJECTRULE);
  991. string updateRule = GetMsdataAttribute(keyref, Keywords.MSD_UPDATERULE);
  992. string deleteRule = GetMsdataAttribute(keyref, Keywords.MSD_DELETERULE);
  993. if (fkc != null) {
  994. if (acceptRejectRule != null)
  995. fkc.AcceptRejectRule = TranslateAcceptRejectRule(acceptRejectRule);
  996. if (updateRule != null)
  997. fkc.UpdateRule = TranslateRule(updateRule);
  998. if (deleteRule != null)
  999. fkc.DeleteRule = TranslateRule(deleteRule);
  1000. SetExtProperties(fkc, keyref.UnhandledAttributes);
  1001. }
  1002. }
  1003. internal void HandleConstraint(XmlSchemaIdentityConstraint keyNode){
  1004. String name = null;
  1005. name = XmlConvert.DecodeName(keyNode.Name);
  1006. if (name==null || name.Length==0)
  1007. throw ExceptionBuilder.MissingAttribute(Keywords.NAME);
  1008. if (ConstraintNodes.ContainsKey(name))
  1009. throw ExceptionBuilder.DuplicateConstraintRead(name);
  1010. // we do not process key defined outside the current node
  1011. String tableName = GetTableName(keyNode);
  1012. string tableNs = GetMsdataAttribute(keyNode,Keywords.MSD_TABLENS);
  1013. DataTable table = _ds.Tables.GetTableSmart(tableName,tableNs);
  1014. if (table == null)
  1015. return;
  1016. ConstraintNodes.Add(name, new ConstraintTable(table, keyNode));
  1017. bool fPrimaryKey = GetBooleanAttribute(keyNode, Keywords.MSD_PRIMARYKEY, /*default:*/ false);
  1018. name = GetStringAttribute(keyNode, "ConstraintName", /*default:*/ name);
  1019. DataColumn[] key = BuildKey(keyNode, table);
  1020. if (0 < key.Length) {
  1021. UniqueConstraint found = (UniqueConstraint) key[0].Table.Constraints.FindConstraint(new UniqueConstraint(name, key));
  1022. if (found == null) {
  1023. key[0].Table.Constraints.Add(name, key, fPrimaryKey);
  1024. SetExtProperties(key[0].Table.Constraints[name], keyNode.UnhandledAttributes);
  1025. }
  1026. else {
  1027. key = found.ColumnsReference;
  1028. SetExtProperties(found, keyNode.UnhandledAttributes);
  1029. if (fPrimaryKey)
  1030. key[0].Table.PrimaryKey = key;
  1031. }
  1032. if (keyNode is XmlSchemaKey) {
  1033. for (int i=0; i<key.Length; i++)
  1034. key[i].AllowDBNull = false;
  1035. }
  1036. }
  1037. }
  1038. internal DataTable InstantiateSimpleTable(XmlSchemaElement node) {
  1039. DataTable table;
  1040. String typeName = XmlConvert.DecodeName(GetInstanceName(node));
  1041. String _TableUri;
  1042. _TableUri = node.QualifiedName.Namespace;
  1043. table = _ds.Tables.GetTable(typeName, _TableUri);
  1044. //
  1045. /* if (table!=null) {
  1046. throw ExceptionBuilder.DuplicateDeclaration(typeName);
  1047. }
  1048. */
  1049. if (!FromInference && table!=null) {
  1050. throw ExceptionBuilder.DuplicateDeclaration(typeName);
  1051. }
  1052. if (table == null) {
  1053. table = new DataTable( typeName);
  1054. table.Namespace = _TableUri;
  1055. // If msdata:targetNamespace node on element, then use it to override table.Namespace.
  1056. table.Namespace = GetStringAttribute(node, "targetNamespace", _TableUri);
  1057. if (!this.FromInference) {
  1058. table.MinOccurs = node.MinOccurs;
  1059. table.MaxOccurs = node.MaxOccurs;
  1060. }
  1061. else {
  1062. string prefix = GetPrefix(_TableUri);
  1063. if (prefix != null)
  1064. table.Prefix = prefix;
  1065. }
  1066. SetProperties(table, node.UnhandledAttributes);
  1067. SetExtProperties(table, node.UnhandledAttributes);
  1068. }
  1069. XmlSchemaComplexType ct = node.SchemaType as XmlSchemaComplexType;
  1070. // We assume node.ElementSchemaType.BaseSchemaType to be null for
  1071. // <xs:element name="foo"/> and not null for <xs:element name="foo" type="xs:string"/>
  1072. bool isSimpleContent = ((node.ElementSchemaType.BaseXmlSchemaType != null) ||(ct != null && ct.ContentModel is XmlSchemaSimpleContent));
  1073. if (!FromInference ||(isSimpleContent && table.Columns.Count == 0 )) {// for inference backward compatability
  1074. HandleElementColumn(node, table, false);
  1075. string colName;
  1076. if (this.FromInference) {
  1077. int i = 0;
  1078. colName = typeName + "_Text";
  1079. while (table.Columns[colName] != null)
  1080. colName = colName + i++;
  1081. }
  1082. else {
  1083. colName = typeName + "_Column";
  1084. }
  1085. table.Columns[0].ColumnName = colName;
  1086. table.Columns[0].ColumnMapping = MappingType.SimpleContent;
  1087. }
  1088. if (!this.FromInference ||_ds.Tables.GetTable(typeName, _TableUri) == null) { // for inference; special case: add table if doesnot exists in collection
  1089. _ds.Tables.Add(table);
  1090. if (this.FromInference) {
  1091. tableDictionary.Add(table, new List<DataTable>());
  1092. }
  1093. }
  1094. // handle all the unique and key constraints related to this table
  1095. if ((dsElement != null) && (dsElement.Constraints!=null)) {
  1096. foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
  1097. if (key is XmlSchemaKeyref)
  1098. continue;
  1099. if (GetTableName(key) == table.TableName)
  1100. HandleConstraint(key);
  1101. }
  1102. }
  1103. table.fNestedInDataset = false;
  1104. return (table);
  1105. }
  1106. internal string GetInstanceName(XmlSchemaAnnotated node) {
  1107. string instanceName = null;
  1108. Debug.Assert( (node is XmlSchemaElement) || (node is XmlSchemaAttribute), "GetInstanceName should only be called on attribute or elements");
  1109. if (node is XmlSchemaElement) {
  1110. XmlSchemaElement el = (XmlSchemaElement) node;
  1111. instanceName = el.Name != null ? el.Name : el.RefName.Name;
  1112. }
  1113. else if (node is XmlSchemaAttribute) {
  1114. XmlSchemaAttribute el = (XmlSchemaAttribute) node;
  1115. instanceName = el.Name != null ? el.Name : el.RefName.Name;
  1116. }
  1117. Debug.Assert((instanceName != null) && (instanceName.Length != 0), "instanceName cannot be null or empty. There's an error in the XSD compiler");
  1118. return instanceName;
  1119. }
  1120. // Sequences of handling Elements, Attributes and Text-only column should be the same as in InferXmlSchema
  1121. internal DataTable InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, bool isRef) {
  1122. DataTable table;
  1123. String typeName = GetInstanceName(node);
  1124. ArrayList tableChildren = new ArrayList();
  1125. String _TableUri;
  1126. _TableUri = node.QualifiedName.Namespace;
  1127. table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), _TableUri);
  1128. // TOD: Do not do this fix
  1129. // if (table == null && node.RefName.IsEmpty && !IsTopLevelElement(node) && _TableUri != null && _TableUri.Length > 0) {
  1130. // _TableUri = null; // it means form="qualified", so child element inherits namespace. [....]
  1131. // }
  1132. if (!FromInference || (FromInference && table == null))
  1133. {
  1134. if (table!=null)
  1135. {
  1136. if (isRef)
  1137. return table;
  1138. else
  1139. throw ExceptionBuilder.DuplicateDeclaration(typeName);
  1140. }
  1141. if (isRef)
  1142. RefTables.Add(_TableUri+":"+typeName);
  1143. table = new DataTable(XmlConvert.DecodeName(typeName) );
  1144. table.TypeName = node.SchemaTypeName;
  1145. table.Namespace = _TableUri;
  1146. table.Namespace = GetStringAttribute(node, "targetNamespace", _TableUri);
  1147. //table.Prefix = node.Prefix;
  1148. String value= GetStringAttribute(typeNode, Keywords.MSD_CASESENSITIVE, "") ;
  1149. if (value.Length ==0)
  1150. {
  1151. value= GetStringAttribute(node, Keywords.MSD_CASESENSITIVE, "") ;
  1152. }
  1153. if (0 < value.Length) {
  1154. if ((value == Keywords.TRUE) || (value == "True"))
  1155. table.CaseSensitive = true;
  1156. if ((value == Keywords.FALSE) || (value == "False"))
  1157. table.CaseSensitive = false;
  1158. }
  1159. value = GetMsdataAttribute(node, Keywords.MSD_LOCALE);
  1160. if (null != value) { // set by user
  1161. if (0 < value.Length) {
  1162. // <... msdata:Locale="en-US"/>
  1163. table.Locale = new CultureInfo(value);
  1164. }
  1165. else {
  1166. // everett bug behavior before <... msdata:Locale=""/> inherit from DataSet
  1167. table.Locale = CultureInfo.InvariantCulture;
  1168. }
  1169. }
  1170. // else inherit from DataSet, not set by user
  1171. if (!this.FromInference)
  1172. {
  1173. table.MinOccurs = node.MinOccurs;
  1174. table.MaxOccurs = node.MaxOccurs;
  1175. }
  1176. else
  1177. {
  1178. string prefix = GetPrefix(_TableUri);
  1179. if (prefix != null)
  1180. table.Prefix = prefix;
  1181. }
  1182. _ds.Tables.Add(table);
  1183. if (FromInference) {
  1184. tableDictionary.Add(table, new List<DataTable>());
  1185. }
  1186. }
  1187. HandleComplexType(typeNode, table, tableChildren, node.IsNillable);
  1188. for (int i=0; i < table.Columns.Count ; i++)
  1189. table.Columns[i].SetOrdinalInternal(i);
  1190. /*
  1191. if (xmlContent == XmlContent.Mixed) {
  1192. string textColumn = GenUniqueColumnName(table.TableName+ "_Text", table);
  1193. table.XmlText = new DataColumn(textColumn, typeof(string), null, MappingType.Text);
  1194. } */
  1195. SetProperties(table, node.UnhandledAttributes);
  1196. SetExtProperties(table, node.UnhandledAttributes);
  1197. // handle all the unique and key constraints related to this table
  1198. if ((dsElement != null) && (dsElement.Constraints!=null)) {
  1199. foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
  1200. if (key is XmlSchemaKeyref)
  1201. continue;
  1202. if (GetTableName(key) == table.TableName) {
  1203. // respect the NS if it is specified for key, otherwise just go with table name check
  1204. if( GetTableNamespace(key) == table.Namespace || GetTableNamespace(key) == null)
  1205. HandleConstraint(key);
  1206. /* if (GetTableNamespace(key) != null) {
  1207. if (GetTableNamespace(key) == table.Namespace)
  1208. HandleConstraint(key);
  1209. }
  1210. else {
  1211. HandleConstraint(key);
  1212. }
  1213. */
  1214. }
  1215. }
  1216. }
  1217. foreach(DataTable _tableChild in tableChildren) {
  1218. if (_tableChild != table && table.Namespace == _tableChild.Namespace)
  1219. _tableChild.tableNamespace = null;
  1220. if ((dsElement != null) && (dsElement.Constraints!=null)) {
  1221. foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
  1222. XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
  1223. if (keyref == null)
  1224. continue;
  1225. bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED, /*default:*/ false);
  1226. if (!isNested)
  1227. continue;
  1228. if (GetTableName(keyref) == _tableChild.TableName) {
  1229. if (_tableChild.DataSet.Tables.InternalIndexOf(_tableChild.TableName) < -1) { // if we have multiple tables with the same name
  1230. if (GetTableNamespace(keyref) == _tableChild.Namespace) {
  1231. HandleKeyref(keyref);
  1232. }
  1233. }
  1234. else {
  1235. HandleKeyref(keyref);
  1236. }
  1237. }
  1238. }
  1239. }
  1240. DataRelation relation = null;
  1241. DataRelationCollection childRelations = table.ChildRelations;
  1242. for (int j = 0; j < childRelations.Count; j++) {
  1243. if (!childRelations[j].Nested)
  1244. continue;
  1245. if (_tableChild == childRelations[j].ChildTable)
  1246. relation = childRelations[j];
  1247. }
  1248. if (relation!=null)
  1249. continue;
  1250. DataColumn parentKey;
  1251. if (this.FromInference) {
  1252. int position = table.UKColumnPositionForInference;// we keep posiotion of unique key column here, for inference
  1253. if (position == -1)
  1254. foreach (DataColumn dc in table.Columns) {
  1255. if (dc.ColumnMapping == MappingType.Attribute) {
  1256. position = dc.Ordinal;
  1257. break;
  1258. }
  1259. }
  1260. parentKey = table.AddUniqueKey(position);
  1261. }
  1262. else {
  1263. parentKey = table.AddUniqueKey();
  1264. }
  1265. // foreign key in the child table
  1266. DataColumn childKey = _tableChild.AddForeignKey(parentKey);
  1267. // when we add unique key, we do set prefix; but for Fk we do not do . So for backward compatability
  1268. if (this.FromInference)
  1269. childKey.Prefix = _tableChild.Prefix;
  1270. // childKey.Prefix = GetPrefix(childKey.Namespace);
  1271. // create relationship
  1272. // setup relationship between parent and this table
  1273. relation = new DataRelation(table.TableName + "_" + _tableChild.TableName, parentKey, childKey, true);
  1274. relation.Nested = true;
  1275. _tableChild.DataSet.Relations.Add(relation);
  1276. if (FromInference && relation.Nested) {
  1277. if (tableDictionary.ContainsKey(relation.ParentTable)) {
  1278. tableDictionary[relation.ParentTable].Add(relation.ChildTable);
  1279. }
  1280. }
  1281. }
  1282. return (table);
  1283. }
  1284. private sealed class NameType : IComparable {
  1285. public readonly String name;
  1286. public readonly Type type;
  1287. public NameType(String n, Type t) {
  1288. name = n;
  1289. type = t;
  1290. }
  1291. public int CompareTo(object obj) { return String.Compare(name, (string)obj, StringComparison.Ordinal); }
  1292. };
  1293. public static Type XsdtoClr(string xsdTypeName) {
  1294. #if DEBUG
  1295. for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
  1296. Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
  1297. }
  1298. #endif
  1299. int index = Array.BinarySearch(mapNameTypeXsd, xsdTypeName);
  1300. if (index < 0) {
  1301. throw ExceptionBuilder.UndefinedDatatype(xsdTypeName);
  1302. }
  1303. return mapNameTypeXsd[index].type;
  1304. }
  1305. // XSD spec: http://www.w3.org/TR/xmlschema-2/
  1306. // April: http://www.w3.org/TR/2000/WD-xmlschema-2-20000407/datatypes.html
  1307. // Fabr: http://www.w3.org/TR/2000/WD-xmlschema-2-20000225/
  1308. private static readonly NameType[] mapNameTypeXsd = {
  1309. new NameType("ENTITIES" , typeof(string) ), /* XSD Apr */
  1310. new NameType("ENTITY" , typeof(string) ), /* XSD Apr */
  1311. new NameType("ID" , typeof(string) ), /* XSD Apr */
  1312. new NameType("IDREF" , typeof(string) ), /* XSD Apr */
  1313. new NameType("IDREFS" , typeof(string) ), /* XSD Apr */
  1314. new NameType("NCName" , typeof(string) ), /* XSD Apr */
  1315. new NameType("NMTOKEN" , typeof(string) ), /* XSD Apr */
  1316. new NameType("NMTOKENS" , typeof(string) ), /* XSD Apr */
  1317. new NameType("NOTATION" , typeof(string) ), /* XSD Apr */
  1318. new NameType("Name" , typeof(string) ), /* XSD Apr */
  1319. new NameType("QName" , typeof(string) ), /* XSD Apr */
  1320. new NameType("anyType" , typeof(System.Object) ), /* XSD Apr */
  1321. new NameType("anyURI" , typeof(System.Uri) ), /* XSD Apr */
  1322. new NameType("base64Binary" , typeof(Byte[]) ), /* XSD Apr : abstruct */
  1323. new NameType("boolean" , typeof(bool) ), /* XSD Apr */
  1324. new NameType("byte" , typeof(SByte) ), /* XSD Apr */
  1325. new NameType("date" , typeof(DateTime)), /* XSD Apr */
  1326. new NameType("dateTime" , typeof(DateTime)), /* XSD Apr */
  1327. new NameType("decimal" , typeof(decimal) ), /* XSD 2001 [....] */
  1328. new NameType("double" , typeof(double) ), /* XSD Apr */
  1329. new NameType("duration" , typeof(TimeSpan)), /* XSD Apr */
  1330. new NameType("float" , typeof(Single) ), /* XSD Apr */
  1331. new NameType("gDay" , typeof(DateTime)), /* XSD Apr */
  1332. new NameType("gMonth" , typeof(DateTime)), /* XSD Apr */
  1333. new NameType("gMonthDay" , typeof(DateTime)), /* XSD Apr */
  1334. new NameType("gYear" , typeof(DateTime)), /* XSD Apr */
  1335. new NameType("gYearMonth" , typeof(DateTime)), /* XSD Apr */
  1336. new NameType("hexBinary" , typeof(Byte[]) ), /* XSD Apr : abstruct */
  1337. new NameType("int" , typeof(Int32) ), /* XSD Apr */
  1338. new NameType("integer" , typeof(Int64) ), /* XSD Apr */ // <xs:element name="" msdata:DataType="System.Numerics.BigInteger" type="xs:integer" minOccurs="0" />
  1339. new NameType("language" , typeof(string) ), /* XSD Apr */
  1340. new NameType("long" , typeof(Int64) ), /* XSD Apr */
  1341. new NameType("negativeInteger" , typeof(Int64) ), /* XSD Apr */
  1342. new NameType("nonNegativeInteger" , typeof(UInt64) ), /* XSD Apr */
  1343. new NameType("nonPositiveInteger" , typeof(Int64) ), /* XSD Apr */
  1344. new NameType("normalizedString" , typeof(string) ), /* XSD Apr */
  1345. new NameType("positiveInteger" , typeof(UInt64) ), /* XSD Apr */
  1346. new NameType("short" , typeof(Int16) ), /* XSD Apr */
  1347. new NameType("string" , typeof(string) ), /* XSD Apr */
  1348. new NameType("time" , typeof(DateTime)), /* XSD Apr */
  1349. new NameType("unsignedByte" , typeof(Byte) ), /* XSD Apr */
  1350. new NameType("unsignedInt" , typeof(UInt32) ), /* XSD Apr */
  1351. new NameType("unsignedLong" , typeof(UInt64) ), /* XSD Apr */
  1352. new NameType("unsignedShort" , typeof(UInt16) ), /* XSD Apr */
  1353. };
  1354. private static NameType FindNameType(string name) {
  1355. #if DEBUG
  1356. for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
  1357. Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
  1358. }
  1359. #endif
  1360. int index = Array.BinarySearch(mapNameTypeXsd, name);
  1361. if (index < 0) {
  1362. throw ExceptionBuilder.UndefinedDatatype(name);
  1363. }
  1364. return mapNameTypeXsd[index];
  1365. }
  1366. // input param dt is a "qName" for UDSimpleType else it assumes it's a XSD builtin simpleType
  1367. private Type ParseDataType(string dt) {
  1368. if (!IsXsdType(dt)) {
  1369. if (udSimpleTypes != null) {
  1370. XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) udSimpleTypes[dt];
  1371. if (simpleType == null) { // it is not named simple type, it is not XSD type, it should be unsupported type like xs:token
  1372. throw ExceptionBuilder.UndefinedDatatype(dt);
  1373. }
  1374. SimpleType rootType = new SimpleType(simpleType);
  1375. while (rootType.BaseSimpleType != null) {
  1376. rootType = rootType.BaseSimpleType;
  1377. }
  1378. return ParseDataType(rootType.BaseType);
  1379. }
  1380. }
  1381. NameType nt = FindNameType(dt);
  1382. return nt.type;
  1383. }
  1384. /* later we may need such a function
  1385. private Boolean IsUDSimpleType(string qname) {
  1386. if (udSimpleTypes == null)
  1387. return false;
  1388. return (udSimpleTypes.Contains(qname));
  1389. }
  1390. */
  1391. internal static Boolean IsXsdType(string name) {
  1392. #if DEBUG
  1393. for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
  1394. Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
  1395. }
  1396. #endif
  1397. int index = Array.BinarySearch(mapNameTypeXsd, name);
  1398. if (index < 0) {
  1399. #if DEBUG
  1400. // Let's check that we realy don't have this name:
  1401. foreach (NameType nt in mapNameTypeXsd) {
  1402. Debug.Assert(nt.name != name, "FindNameType('" + name + "') -- failed. Existed name not found");
  1403. }
  1404. #endif
  1405. return false;
  1406. }
  1407. Debug.Assert(mapNameTypeXsd[index].name == name, "FindNameType('" + name + "') -- failed. Wrong name found");
  1408. return true;
  1409. }
  1410. internal XmlSchemaAnnotated FindTypeNode(XmlSchemaAnnotated node) {
  1411. // this function is returning null
  1412. // if the typeNode for node is in the XSD namespace.
  1413. XmlSchemaAttribute attr = node as XmlSchemaAttribute;
  1414. XmlSchemaElement el = node as XmlSchemaElement;
  1415. bool isAttr = false;
  1416. if (attr != null) {
  1417. isAttr = true;
  1418. }
  1419. String _type = isAttr ? attr.SchemaTypeName.Name : el.SchemaTypeName.Name;
  1420. String _typeNs = isAttr ? attr.SchemaTypeName.Namespace : el.SchemaTypeName.Namespace;
  1421. if (_typeNs == Keywords.XSDNS)
  1422. return null;
  1423. XmlSchemaAnnotated typeNode;
  1424. if (_type == null || _type.Length == 0) {
  1425. _type = isAttr ? attr.RefName.Name : el.RefName.Name;
  1426. if (_type == null || _type.Length == 0)
  1427. typeNode = (XmlSchemaAnnotated) (isAttr ? attr.SchemaType : el.SchemaType);
  1428. else
  1429. typeNode = isAttr ? FindTypeNode((XmlSchemaAnnotated)attributes[attr.RefName]) :FindTypeNode((XmlSchemaAnnotated)elementsTable[el.RefName]);
  1430. }
  1431. else
  1432. typeNode = (XmlSchemaAnnotated)schemaTypes[isAttr ? ((XmlSchemaAttribute)node).SchemaTypeName : ((XmlSchemaElement)node).SchemaTypeName];
  1433. return typeNode;
  1434. }
  1435. internal void HandleSimpleTypeSimpleContentColumn(XmlSchemaSimpleType typeNode, string strType, DataTable table, bool isBase, XmlAttribute[] attrs, bool isNillable){
  1436. // disallow multiple simple content columns for the table
  1437. if(FromInference && table.XmlText != null) { // backward compatability for inference
  1438. return;
  1439. }
  1440. Type type = null;
  1441. SimpleType xsdType = null;
  1442. // if (typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
  1443. if (typeNode.QualifiedName.Name != null && typeNode.QualifiedName.Name.Length != 0 && typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
  1444. xsdType = new SimpleType(typeNode);
  1445. strType = typeNode.QualifiedName.ToString(); // use qualifed name
  1446. type = ParseDataType(typeNode.QualifiedName.ToString());
  1447. }
  1448. else {// previous code V 1.1
  1449. XmlSchemaSimpleType ancestor = typeNode.BaseXmlSchemaType as XmlSchemaSimpleType;
  1450. if ((ancestor != null) && (ancestor.QualifiedName.Namespace != Keywords.XSDNS)) {
  1451. xsdType = new SimpleType(typeNode);
  1452. SimpleType rootType = xsdType;
  1453. while (rootType.BaseSimpleType != null) {
  1454. rootType = rootType.BaseSimpleType;
  1455. }
  1456. type = ParseDataType(rootType.BaseType);
  1457. strType = xsdType.Name;
  1458. }
  1459. else {
  1460. type = ParseDataType(strType);
  1461. }
  1462. }
  1463. DataColumn column;
  1464. string colName;
  1465. if (this.FromInference) {
  1466. int i = 0;
  1467. colName = table.TableName + "_Text";
  1468. while (table.Columns[colName] != null) {
  1469. colName = colName + i++;
  1470. }
  1471. }
  1472. else
  1473. colName = table.TableName + "_text";
  1474. string columnName = colName;
  1475. bool isToAdd = true;
  1476. if ((!isBase) && (table.Columns.Contains(columnName, true))){
  1477. column = table.Columns[columnName];
  1478. isToAdd = false;
  1479. }
  1480. else {
  1481. column = new DataColumn(columnName, type, null, MappingType.SimpleContent);
  1482. }
  1483. SetProperties(column, attrs);
  1484. HandleColumnExpression(column, attrs);
  1485. SetExtProperties(column, attrs);
  1486. String tmp = (-1).ToString(CultureInfo.CurrentCulture);
  1487. string defValue = null;
  1488. //try to see if attributes contain allownull
  1489. column.AllowDBNull = isNillable;
  1490. if(attrs!=null)
  1491. for(int i=0; i< attrs.Length;i++) {
  1492. if ( attrs[i].LocalName == Keywords.MSD_ALLOWDBNULL && attrs[i].NamespaceURI == Keywords.MSDNS)
  1493. if ( attrs[i].Value == Keywords.FALSE)
  1494. column.AllowDBNull = false;
  1495. if ( attrs[i].LocalName == Keywords.MSD_ORDINAL && attrs[i].NamespaceURI == Keywords.MSDNS)
  1496. tmp = attrs[i].Value;
  1497. if ( attrs[i].LocalName == Keywords.MSD_DEFAULTVALUE && attrs[i].NamespaceURI == Keywords.MSDNS)
  1498. defValue = attrs[i].Value;
  1499. }
  1500. int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
  1501. //SetExtProperties(column, attr.UnhandledAttributes);
  1502. if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
  1503. ColumnExpressions.Add(column);
  1504. }
  1505. // Update XSD type to point to simple types actual namespace instead of normalized default namespace in case of remoting
  1506. if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
  1507. if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
  1508. column.XmlDataType = xsdType.SimpleTypeQualifiedName;
  1509. }
  1510. }
  1511. else {
  1512. column.XmlDataType = strType;
  1513. }
  1514. column.SimpleType = xsdType;
  1515. //column.Namespace = typeNode.SourceUri;
  1516. if (isToAdd) {
  1517. if (this.FromInference) {
  1518. column.Prefix = GetPrefix(table.Namespace);
  1519. column.AllowDBNull = true;
  1520. }
  1521. if(ordinal>-1 && ordinal<table.Columns.Count)
  1522. table.Columns.AddAt(ordinal, column);
  1523. else
  1524. table.Columns.Add(column);
  1525. }
  1526. if (defValue != null)
  1527. try {
  1528. column.DefaultValue = column.ConvertXmlToObject(defValue);
  1529. }
  1530. catch (System.FormatException) {
  1531. throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
  1532. }
  1533. }
  1534. internal void HandleSimpleContentColumn(String strType, DataTable table, bool isBase, XmlAttribute[] attrs, bool isNillable){
  1535. // for Named Simple type support : We should not recieved anything here other than string.
  1536. // there can not be typed simple content
  1537. // disallow multiple simple content columns for the table
  1538. if(this.FromInference && table.XmlText != null) // backward compatability for inference
  1539. return;
  1540. Type type = null;
  1541. if (strType == null) {
  1542. return;
  1543. }
  1544. type = ParseDataType(strType); // we pass it correctly when we call the method, no need to special check.
  1545. DataColumn column;
  1546. string colName;
  1547. if (this.FromInference) {
  1548. int i = 0;
  1549. colName = table.TableName + "_Text";
  1550. while (table.Columns[colName] != null) {
  1551. colName = colName + i++;
  1552. }
  1553. }
  1554. else
  1555. colName = table.TableName + "_text";
  1556. string columnName = colName;
  1557. bool isToAdd = true;
  1558. if ((!isBase) && (table.Columns.Contains(columnName, true))){
  1559. column = table.Columns[columnName];
  1560. isToAdd = false;
  1561. }
  1562. else {
  1563. column = new DataColumn(columnName, type, null, MappingType.SimpleContent);
  1564. }
  1565. SetProperties(column, attrs);
  1566. HandleColumnExpression(column, attrs);
  1567. SetExtProperties(column, attrs);
  1568. String tmp = (-1).ToString(CultureInfo.CurrentCulture);
  1569. string defValue = null;
  1570. //try to see if attributes contain allownull
  1571. column.AllowDBNull = isNillable;
  1572. if(attrs!=null)
  1573. for(int i=0; i< attrs.Length;i++) {
  1574. if ( attrs[i].LocalName == Keywords.MSD_ALLOWDBNULL && attrs[i].NamespaceURI == Keywords.MSDNS)
  1575. if ( attrs[i].Value == Keywords.FALSE)
  1576. column.AllowDBNull = false;
  1577. if ( attrs[i].LocalName == Keywords.MSD_ORDINAL && attrs[i].NamespaceURI == Keywords.MSDNS)
  1578. tmp = attrs[i].Value;
  1579. if ( attrs[i].LocalName == Keywords.MSD_DEFAULTVALUE && attrs[i].NamespaceURI == Keywords.MSDNS)
  1580. defValue = attrs[i].Value;
  1581. }
  1582. int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
  1583. //SetExtProperties(column, attr.UnhandledAttributes);
  1584. if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
  1585. ColumnExpressions.Add(column);
  1586. }
  1587. column.XmlDataType = strType;
  1588. column.SimpleType = null;
  1589. //column.Namespace = typeNode.SourceUri;
  1590. if(this.FromInference)
  1591. column.Prefix = GetPrefix(column.Namespace);
  1592. if (isToAdd) {
  1593. if (this.FromInference) // move this setting to SetProperties
  1594. column.AllowDBNull = true;
  1595. if(ordinal>-1 && ordinal<table.Columns.Count)
  1596. table.Columns.AddAt(ordinal, column);
  1597. else
  1598. table.Columns.Add(column);
  1599. }
  1600. if (defValue != null)
  1601. try {
  1602. column.DefaultValue = column.ConvertXmlToObject(defValue);
  1603. }
  1604. catch (System.FormatException) {
  1605. throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
  1606. }
  1607. }
  1608. internal void HandleAttributeColumn(XmlSchemaAttribute attrib, DataTable table, bool isBase){
  1609. Type type = null;
  1610. XmlSchemaAttribute attr = attrib.Name != null ? attrib : (XmlSchemaAttribute) attributes[attrib.RefName];
  1611. XmlSchemaAnnotated typeNode = FindTypeNode(attr);
  1612. String strType = null;
  1613. SimpleType xsdType = null;
  1614. if (typeNode == null) {
  1615. strType = attr.SchemaTypeName.Name;
  1616. if (Common.ADP.IsEmpty(strType)) {
  1617. strType = "";
  1618. type = typeof(string);
  1619. }
  1620. else {
  1621. if (attr.SchemaTypeName.Namespace != Keywords.XSDNS) // it is UD Simple Type, can it be?
  1622. //
  1623. type = ParseDataType(attr.SchemaTypeName.ToString());
  1624. else
  1625. type = ParseDataType(attr.SchemaTypeName.Name);
  1626. }
  1627. }
  1628. else if (typeNode is XmlSchemaSimpleType) {
  1629. //
  1630. XmlSchemaSimpleType node = typeNode as XmlSchemaSimpleType;
  1631. xsdType = new SimpleType(node);
  1632. if (node.QualifiedName.Name != null && node.QualifiedName.Name.Length != 0 && node.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
  1633. strType = node.QualifiedName.ToString(); // use qualifed name
  1634. type = ParseDataType(node.QualifiedName.ToString());// search with QName
  1635. }
  1636. else {
  1637. type = ParseDataType(xsdType.BaseType);
  1638. strType = xsdType.Name;
  1639. if(xsdType.Length == 1 && type == typeof(string)) {
  1640. type = typeof(Char);
  1641. }
  1642. }
  1643. }
  1644. else if (typeNode is XmlSchemaElement) {
  1645. strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
  1646. type = ParseDataType(strType);
  1647. }
  1648. else {
  1649. if (typeNode.Id == null)
  1650. throw ExceptionBuilder.DatatypeNotDefined();
  1651. else
  1652. throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
  1653. }
  1654. DataColumn column;
  1655. string columnName = XmlConvert.DecodeName(GetInstanceName(attr));
  1656. bool isToAdd = true;
  1657. if ((!isBase || FromInference) && (table.Columns.Contains(columnName, true))) {
  1658. column = table.Columns[columnName];
  1659. isToAdd = false;
  1660. if (FromInference) { // for backward compatability with old inference
  1661. // throw eception if same column is being aded with different mapping
  1662. if (column.ColumnMapping != MappingType.Attribute)
  1663. throw ExceptionBuilder.ColumnTypeConflict(column.ColumnName);
  1664. // in previous inference , if we have incoming column with different NS, we think as different column and
  1665. //while adding , since there is no NS concept for datacolumn, we used to throw exception
  1666. // simulate the same behavior.
  1667. if ((Common.ADP.IsEmpty(attrib.QualifiedName.Namespace) && Common.ADP.IsEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
  1668. (string.Compare(attrib.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal) == 0))
  1669. {
  1670. return; // backward compatability
  1671. }
  1672. column = new DataColumn(columnName, type, null, MappingType.Attribute); // this is to fix issue with Exception we used to throw for old inference engine if column
  1673. //exists with different namespace; while adding it to columncollection
  1674. isToAdd = true;
  1675. }
  1676. }
  1677. else {
  1678. column = new DataColumn(columnName, type, null, MappingType.Attribute);
  1679. }
  1680. SetProperties(column, attr.UnhandledAttributes);
  1681. HandleColumnExpression(column, attr.UnhandledAttributes);
  1682. SetExtProperties(column, attr.UnhandledAttributes);
  1683. if ((column.Expression!=null)&&(column.Expression.Length!=0)) {
  1684. ColumnExpressions.Add(column);
  1685. }
  1686. if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
  1687. if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
  1688. column.XmlDataType = xsdType.SimpleTypeQualifiedName;
  1689. }
  1690. }
  1691. else {
  1692. column.XmlDataType = strType;
  1693. }
  1694. column.SimpleType = xsdType;
  1695. column.AllowDBNull = !(attrib.Use == XmlSchemaUse.Required);
  1696. column.Namespace = attrib.QualifiedName.Namespace;
  1697. column.Namespace = GetStringAttribute(attrib, "targetNamespace", column.Namespace);
  1698. if (isToAdd) {
  1699. if (this.FromInference) { // move this setting to SetProperties
  1700. column.AllowDBNull = true;
  1701. column.Prefix = GetPrefix(column.Namespace);
  1702. }
  1703. table.Columns.Add(column);
  1704. }
  1705. if (attrib.Use == XmlSchemaUse.Prohibited) {
  1706. column.ColumnMapping = MappingType.Hidden;
  1707. column.AllowDBNull = GetBooleanAttribute(attr, Keywords.MSD_ALLOWDBNULL, true) ;
  1708. String defValue = GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE);
  1709. if (defValue != null)
  1710. try {
  1711. column.DefaultValue = column.ConvertXmlToObject(defValue);
  1712. }
  1713. catch (System.FormatException) {
  1714. throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
  1715. }
  1716. }
  1717. // XDR [....] change
  1718. string strDefault = (attrib.Use == XmlSchemaUse.Required) ? GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE) : attr.DefaultValue;
  1719. if ((attr.Use == XmlSchemaUse.Optional) && (strDefault == null ))
  1720. strDefault = attr.FixedValue;
  1721. if (strDefault != null)
  1722. try {
  1723. column.DefaultValue = column.ConvertXmlToObject(strDefault);
  1724. }
  1725. catch (System.FormatException) {
  1726. throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
  1727. }
  1728. }
  1729. internal void HandleElementColumn(XmlSchemaElement elem, DataTable table, bool isBase){
  1730. Type type = null;
  1731. XmlSchemaElement el = elem.Name != null ? elem : (XmlSchemaElement) elementsTable[elem.RefName];
  1732. if (el == null) // it's possible due to some XSD compiler optimizations
  1733. return; // do nothing
  1734. XmlSchemaAnnotated typeNode = FindTypeNode(el);
  1735. String strType = null;
  1736. SimpleType xsdType = null;
  1737. if (typeNode == null) {
  1738. strType = el.SchemaTypeName.Name;
  1739. if (Common.ADP.IsEmpty(strType)) {
  1740. strType = "";
  1741. type = typeof(string);
  1742. }
  1743. else {
  1744. type = ParseDataType(el.SchemaTypeName.Name);
  1745. }
  1746. }
  1747. else if (typeNode is XmlSchemaSimpleType) {
  1748. //
  1749. XmlSchemaSimpleType simpleTypeNode = typeNode as XmlSchemaSimpleType;
  1750. xsdType = new SimpleType(simpleTypeNode);
  1751. // ((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 check is for annonymos simple type,
  1752. // it should be user defined Named simple type
  1753. if (((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 && ((XmlSchemaSimpleType)typeNode).QualifiedName.Namespace != Keywords.XSDNS) {
  1754. string targetNamespace = XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE);
  1755. strType = ((XmlSchemaSimpleType)typeNode).QualifiedName.ToString(); // use qualifed name
  1756. type = ParseDataType(strType);
  1757. }
  1758. else {
  1759. simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS) ?
  1760. schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
  1761. null;
  1762. while (simpleTypeNode != null) {
  1763. xsdType.LoadTypeValues(simpleTypeNode);
  1764. simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS) ?
  1765. schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
  1766. null;
  1767. }
  1768. type = ParseDataType(xsdType.BaseType);
  1769. strType = xsdType.Name;
  1770. if(xsdType.Length == 1 && type == typeof(string)) {
  1771. type = typeof(Char);
  1772. }
  1773. }
  1774. }
  1775. else if (typeNode is XmlSchemaElement) { // theoratically no named simpletype should come here
  1776. strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
  1777. type = ParseDataType(strType);
  1778. }
  1779. else if (typeNode is XmlSchemaComplexType) {
  1780. if (ADP.IsEmpty(XSDSchema.GetMsdataAttribute(elem, Keywords.MSD_DATATYPE))) {
  1781. throw ExceptionBuilder.DatatypeNotDefined();
  1782. }
  1783. else {
  1784. type = typeof(object);
  1785. }
  1786. }
  1787. else {
  1788. if (typeNode.Id == null)
  1789. throw ExceptionBuilder.DatatypeNotDefined();
  1790. else
  1791. throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
  1792. }
  1793. DataColumn column;
  1794. string columnName = XmlConvert.DecodeName(GetInstanceName(el));
  1795. bool isToAdd = true;
  1796. if (((!isBase) || FromInference) && (table.Columns.Contains(columnName, true))) {
  1797. column = table.Columns[columnName];
  1798. isToAdd = false;
  1799. if (FromInference) { // for backward compatability with old inference
  1800. if (column.ColumnMapping != MappingType.Element)
  1801. throw ExceptionBuilder.ColumnTypeConflict(column.ColumnName);
  1802. // in previous inference , if we have incoming column with different NS, we think as different column and
  1803. //while adding , since there is no NS concept for datacolumn, we used to throw exception
  1804. // simulate the same behavior.
  1805. if ((Common.ADP.IsEmpty(elem.QualifiedName.Namespace) && Common.ADP.IsEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
  1806. (string.Compare(elem.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal) == 0))
  1807. {
  1808. return; // backward compatability
  1809. }
  1810. column = new DataColumn(columnName, type, null, MappingType.Element);// this is to fix issue with Exception we used to throw for old inference engine if column
  1811. //exists with different namespace; while adding it to columncollection
  1812. isToAdd = true;
  1813. }
  1814. }
  1815. else {
  1816. column = new DataColumn(columnName, type, null, MappingType.Element);
  1817. }
  1818. SetProperties(column, el.UnhandledAttributes);
  1819. HandleColumnExpression(column, el.UnhandledAttributes);
  1820. SetExtProperties(column, el.UnhandledAttributes);
  1821. if (!Common.ADP.IsEmpty(column.Expression)) {
  1822. ColumnExpressions.Add(column);
  1823. }
  1824. // Update XSD type to point to simple types actual namespace instead of normalized default namespace in case of remoting
  1825. if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0) {
  1826. if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE)!= null) {
  1827. column.XmlDataType = xsdType.SimpleTypeQualifiedName;
  1828. }
  1829. }
  1830. else {
  1831. column.XmlDataType = strType;
  1832. }
  1833. column.SimpleType = xsdType;
  1834. column.AllowDBNull = this.FromInference ||(elem.MinOccurs == 0 ) || elem.IsNillable;
  1835. if (!elem.RefName.IsEmpty || elem.QualifiedName.Namespace != table.Namespace)
  1836. { // if ref element (or in diferent NS) it is global element, so form MUST BE Qualified
  1837. column.Namespace = elem.QualifiedName.Namespace;
  1838. column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
  1839. }
  1840. else { // it is local, hence check for 'form' on local element, if not specified, check for 'elemenfformdefault' on schema element
  1841. if (elem.Form == XmlSchemaForm.Unqualified) {
  1842. column.Namespace = String.Empty;
  1843. }
  1844. else if (elem.Form == XmlSchemaForm.None) {
  1845. XmlSchemaObject e = (XmlSchemaObject)elem.Parent;
  1846. while (e.Parent != null) {
  1847. e = e.Parent;
  1848. }
  1849. if (((XmlSchema)e).ElementFormDefault == XmlSchemaForm.Unqualified) {
  1850. column.Namespace = String.Empty;
  1851. }
  1852. }
  1853. else {
  1854. column.Namespace = elem.QualifiedName.Namespace;
  1855. column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
  1856. }
  1857. }
  1858. String tmp = GetStringAttribute(elem, Keywords.MSD_ORDINAL, (-1).ToString(CultureInfo.CurrentCulture));
  1859. int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
  1860. if(isToAdd) {
  1861. if(ordinal>-1 && ordinal<table.Columns.Count)
  1862. table.Columns.AddAt(ordinal, column);
  1863. else
  1864. table.Columns.Add(column);
  1865. }
  1866. if (column.Namespace == table.Namespace)
  1867. column._columnUri = null; // to not raise a column change namespace again
  1868. if(this.FromInference) {// search for prefix after adding to table, so NS has its final value, and
  1869. column.Prefix = GetPrefix(column.Namespace); // it can inherit its NS from DataTable, if it is null
  1870. }
  1871. string strDefault = el.DefaultValue;
  1872. if (strDefault != null )
  1873. try {
  1874. column.DefaultValue = column.ConvertXmlToObject(strDefault);
  1875. }
  1876. catch (System.FormatException) {
  1877. throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
  1878. }
  1879. }
  1880. internal void HandleDataSet(XmlSchemaElement node, bool isNewDataSet) {
  1881. string dsName = node.Name;
  1882. string dsNamespace = node.QualifiedName.Namespace;
  1883. int initialTableCount = _ds.Tables.Count; // just use for inference backward compatablity
  1884. List<DataTable> tableSequenceList = new List<DataTable>();
  1885. String value = GetMsdataAttribute(node, Keywords.MSD_LOCALE);
  1886. if (null != value) { // set by user
  1887. if (0 != value.Length) {
  1888. // <... msdata:Locale="en-US"/>
  1889. _ds.Locale = new CultureInfo(value);
  1890. }
  1891. else {
  1892. // everett bug behavior before <... msdata:Locale=""/> becoming CultureInfo(0x409)
  1893. _ds.Locale = CultureInfo.InvariantCulture;
  1894. }
  1895. }
  1896. else { // not set by user
  1897. // MSD_LOCALE overrides MSD_USECURRENTLOCALE
  1898. if (GetBooleanAttribute(node, Keywords.MSD_USECURRENTLOCALE, false)) {
  1899. _ds.SetLocaleValue(CultureInfo.CurrentCulture, false);
  1900. }
  1901. else {
  1902. // everett behavior before <... msdata:UseCurrentLocale="true"/>
  1903. _ds.SetLocaleValue(new CultureInfo(0x409), false);
  1904. }
  1905. }
  1906. // reuse variable
  1907. value = GetMsdataAttribute(node, Keywords.MSD_DATASETNAME);
  1908. if (value!=null && value.Length != 0) {
  1909. dsName = value;
  1910. }
  1911. value = GetMsdataAttribute(node, Keywords.MSD_DATASETNAMESPACE);
  1912. if (value!=null && value.Length != 0) {
  1913. dsNamespace = value;
  1914. }
  1915. SetProperties(_ds, node.UnhandledAttributes);
  1916. SetExtProperties(_ds, node.UnhandledAttributes);
  1917. if (dsName != null && dsName.Length != 0)
  1918. _ds.DataSetName = XmlConvert.DecodeName(dsName);
  1919. // _ds.Namespace = node.QualifiedName.Namespace;
  1920. _ds.Namespace = dsNamespace;
  1921. if (this.FromInference)
  1922. _ds.Prefix = GetPrefix(_ds.Namespace);
  1923. XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(node);
  1924. if (ct.Particle != null) {
  1925. XmlSchemaObjectCollection items = GetParticleItems(ct.Particle);
  1926. if (items == null) {
  1927. return;
  1928. }
  1929. foreach (XmlSchemaAnnotated el in items){
  1930. if (el is XmlSchemaElement) {
  1931. if(((XmlSchemaElement)el).RefName.Name.Length != 0) {
  1932. if (!FromInference) {
  1933. continue;
  1934. }
  1935. else {
  1936. DataTable tempTable = _ds.Tables.GetTable(XmlConvert.DecodeName(GetInstanceName((XmlSchemaElement)el)), node.QualifiedName.Namespace);
  1937. if (tempTable != null) {
  1938. tableSequenceList.Add(tempTable); // if ref table is created, add it
  1939. }
  1940. bool isComplexTypeOrValidElementType = false;
  1941. if (node.ElementSchemaType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) {
  1942. isComplexTypeOrValidElementType = true;
  1943. }
  1944. // bool isComplexTypeOrValidElementType = (node.ElementType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType));
  1945. if ((((XmlSchemaElement)el).MaxOccurs != Decimal.One ) && (!isComplexTypeOrValidElementType)) {
  1946. continue;
  1947. }
  1948. }
  1949. }
  1950. DataTable child = HandleTable ((XmlSchemaElement)el);
  1951. if (child!=null) {
  1952. child.fNestedInDataset = true;
  1953. }
  1954. if (FromInference) {
  1955. tableSequenceList.Add(child);
  1956. }
  1957. }
  1958. else if (el is XmlSchemaChoice){ // should we check for inference?
  1959. XmlSchemaObjectCollection choiceItems = ((XmlSchemaChoice)el).Items;
  1960. if (choiceItems == null)
  1961. continue;
  1962. foreach (XmlSchemaAnnotated choiceEl in choiceItems) {
  1963. if (choiceEl is XmlSchemaElement) {
  1964. if (((XmlSchemaParticle)el).MaxOccurs > Decimal.One && (((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)) // amir
  1965. ((XmlSchemaElement)choiceEl).MaxOccurs = ((XmlSchemaParticle)el).MaxOccurs;
  1966. if ((((XmlSchemaElement)choiceEl).RefName.Name.Length != 0) && (!FromInference && ((XmlSchemaElement)choiceEl).MaxOccurs != Decimal.One && !(((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)))
  1967. continue;
  1968. DataTable child = HandleTable ((XmlSchemaElement)choiceEl);
  1969. if (FromInference) {
  1970. tableSequenceList.Add(child);
  1971. }
  1972. if (child != null)
  1973. {
  1974. child.fNestedInDataset = true;
  1975. }
  1976. }
  1977. }
  1978. }
  1979. }
  1980. }
  1981. // Handle the non-nested keyref constraints
  1982. if (node.Constraints != null) {
  1983. foreach (XmlSchemaIdentityConstraint key in node.Constraints) {
  1984. XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
  1985. if (keyref == null)
  1986. continue;
  1987. bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED, /*default:*/ false);
  1988. if (isNested)
  1989. continue;
  1990. HandleKeyref(keyref);
  1991. }
  1992. }
  1993. if (FromInference && isNewDataSet) {
  1994. List<DataTable> _tableList = new List<DataTable>(_ds.Tables.Count);
  1995. foreach(DataTable dt in tableSequenceList) {
  1996. AddTablesToList(_tableList, dt);
  1997. }
  1998. _ds.Tables.ReplaceFromInference(_tableList); // replace the list with the one in correct order: BackWard compatability for inference
  1999. }
  2000. }
  2001. private void AddTablesToList(List<DataTable> tableList, DataTable dt) { // kind of depth _first travarsal
  2002. if (!tableList.Contains(dt)) {
  2003. tableList.Add(dt);
  2004. foreach(DataTable childTable in tableDictionary[dt]) {
  2005. AddTablesToList(tableList, childTable);
  2006. }
  2007. }
  2008. }
  2009. private string GetPrefix(string ns) {
  2010. if (ns == null)
  2011. return null;
  2012. foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) {
  2013. XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray();
  2014. for(int i = 0; i < qualifiedNames.Length; i++) {
  2015. if (qualifiedNames[i].Namespace == ns)
  2016. return qualifiedNames[i].Name;
  2017. }
  2018. }
  2019. return null;
  2020. }
  2021. private string GetNamespaceFromPrefix(string prefix) {
  2022. if ((prefix == null) ||(prefix.Length == 0))
  2023. return null;
  2024. foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) {
  2025. XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray();
  2026. for(int i = 0; i < qualifiedNames.Length; i++) {
  2027. if (qualifiedNames[i].Name == prefix)
  2028. return qualifiedNames[i].Namespace;
  2029. }
  2030. }
  2031. return null;
  2032. }
  2033. private String GetTableNamespace(XmlSchemaIdentityConstraint key) {
  2034. string xpath = key.Selector.XPath;
  2035. string [] split = xpath.Split('/');
  2036. string prefix =string.Empty;
  2037. string QualifiedTableName = split[split.Length - 1]; //get the last string after '/' and ':'
  2038. if ((QualifiedTableName == null) || (QualifiedTableName.Length == 0))
  2039. throw ExceptionBuilder.InvalidSelector(xpath);
  2040. if (QualifiedTableName.IndexOf(':') != -1)
  2041. prefix = QualifiedTableName.Substring(0, QualifiedTableName.IndexOf(':'));
  2042. else
  2043. return GetMsdataAttribute(key, Keywords.MSD_TABLENS);
  2044. prefix = XmlConvert.DecodeName(prefix );
  2045. return GetNamespaceFromPrefix(prefix);
  2046. }
  2047. private String GetTableName(XmlSchemaIdentityConstraint key) {
  2048. string xpath = key.Selector.XPath;
  2049. string [] split = xpath.Split('/',':');
  2050. String tableName = split[split.Length - 1]; //get the last string after '/' and ':'
  2051. if ((tableName == null) || (tableName.Length == 0))
  2052. throw ExceptionBuilder.InvalidSelector(xpath);
  2053. tableName = XmlConvert.DecodeName(tableName);
  2054. return tableName;
  2055. }
  2056. internal bool IsTable(XmlSchemaElement node) {
  2057. if (node.MaxOccurs == decimal.Zero)
  2058. return false;
  2059. XmlAttribute[] attribs = node.UnhandledAttributes;
  2060. if (attribs != null) {
  2061. for(int i = 0; i < attribs.Length; i++) {
  2062. XmlAttribute attrib = attribs[i];
  2063. if (attrib.LocalName == Keywords.MSD_DATATYPE &&
  2064. attrib.Prefix == Keywords.MSD &&
  2065. attrib.NamespaceURI == Keywords.MSDNS)
  2066. return false;
  2067. }
  2068. }
  2069. Object typeNode = FindTypeNode(node);
  2070. if ( (node.MaxOccurs > decimal.One) && typeNode == null ){
  2071. return true;
  2072. }
  2073. if ((typeNode==null) || !(typeNode is XmlSchemaComplexType)) {
  2074. return false;
  2075. }
  2076. XmlSchemaComplexType ctNode = (XmlSchemaComplexType) typeNode;
  2077. if (ctNode.IsAbstract)
  2078. throw ExceptionBuilder.CannotInstantiateAbstract(node.Name);
  2079. return true;
  2080. }
  2081. // internal bool IsTopLevelElement (XmlSchemaElement node) {
  2082. // return (elements.IndexOf(node) != -1);
  2083. // }
  2084. internal DataTable HandleTable(XmlSchemaElement node) {
  2085. if (!IsTable(node))
  2086. return null;
  2087. Object typeNode = FindTypeNode(node);
  2088. if ( (node.MaxOccurs > decimal.One) && typeNode == null ){
  2089. return InstantiateSimpleTable(node);
  2090. }
  2091. DataTable table = InstantiateTable(node,(XmlSchemaComplexType)typeNode, (node.RefName != null)); // this is wrong , correct check should be node.RefName.IsEmpty
  2092. table.fNestedInDataset = false;
  2093. return table;
  2094. }
  2095. }
  2096. internal sealed class XmlIgnoreNamespaceReader : XmlNodeReader {
  2097. private List<string> namespacesToIgnore;
  2098. //
  2099. // Constructor
  2100. //
  2101. internal XmlIgnoreNamespaceReader(XmlDocument xdoc, string[] namespacesToIgnore) : base(xdoc) {
  2102. this.namespacesToIgnore = new List<string>(namespacesToIgnore);
  2103. }
  2104. //
  2105. // XmlReader implementation
  2106. //
  2107. public override bool MoveToFirstAttribute() {
  2108. if (base.MoveToFirstAttribute()) {
  2109. if ( namespacesToIgnore.Contains(this.NamespaceURI) ||
  2110. (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) { //try next one
  2111. return MoveToNextAttribute();
  2112. }
  2113. else {
  2114. return true;
  2115. }
  2116. }
  2117. return false;
  2118. }
  2119. public override bool MoveToNextAttribute() {
  2120. bool moved, flag;
  2121. do {
  2122. moved = false;
  2123. flag = false;
  2124. if (base.MoveToNextAttribute()) {
  2125. moved = true;
  2126. if ( namespacesToIgnore.Contains(this.NamespaceURI) ||
  2127. (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) {
  2128. flag = true;
  2129. }
  2130. }
  2131. } while(flag);
  2132. return moved;
  2133. }
  2134. }
  2135. }