Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / XDRSchema.cs / 1 / XDRSchema.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Xml; using System.Collections; using System.Globalization; using System.ComponentModel; using System.Diagnostics; using System.Data.Common; internal sealed class XDRSchema : XMLSchema { internal String _schemaName; internal String _schemaUri; internal XmlElement _schemaRoot; internal DataSet _ds; private static char[] colonArray = new char[] {':'}; internal XDRSchema(DataSet ds, bool fInline) { _schemaUri = String.Empty; _schemaName = String.Empty; _schemaRoot = null; _ds = ds; } internal void LoadSchema(XmlElement schemaRoot, DataSet ds) { if (schemaRoot == null) return; _schemaRoot = schemaRoot; _ds = ds; _schemaName = schemaRoot.GetAttribute(Keywords.NAME); _schemaUri = ""; Debug.Assert(FEqualIdentity(schemaRoot, Keywords.XDR_SCHEMA, Keywords.XDRNS), "Illegal node"); // Get Locale and CaseSensitive properties if (_schemaName == null || _schemaName.Length == 0) _schemaName = "NewDataSet"; ds.Namespace = _schemaUri; // Walk all the top level Element tags. for (XmlNode n = schemaRoot.FirstChild; n != null; n = n.NextSibling) { if (!(n is XmlElement)) continue; XmlElement child = (XmlElement) n; if (FEqualIdentity(child, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS)) { HandleTable(child); } } _schemaName = XmlConvert.DecodeName(_schemaName); if (ds.Tables[_schemaName] == null) ds.DataSetName = _schemaName; } internal XmlElement FindTypeNode(XmlElement node) { string strType; XmlNode vn; XmlNode vnRoof; Debug.Assert(FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_SCHEMA, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS), "Invalid node type " + node.LocalName); if (FEqualIdentity(node, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS)) return node; strType = node.GetAttribute(Keywords.TYPE); if (FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS)) { if (strType == null || strType.Length == 0) return null; // Find an ELEMENTTYPE or ATTRIBUTETYPE with name=strType vn = node.OwnerDocument.FirstChild; vnRoof = node.OwnerDocument; while (vn != vnRoof) { if ((FEqualIdentity(vn, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS) && FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS)) || (FEqualIdentity(vn, Keywords.XDR_ATTRIBUTETYPE, Keywords.XDRNS) && FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS))) { if (vn is XmlElement && ((XmlElement)vn).GetAttribute(Keywords.NAME) == strType) return(XmlElement)vn; } // Move vn node if (vn.FirstChild != null) vn = vn.FirstChild; else if (vn.NextSibling != null) vn = vn.NextSibling; else { while (vn != vnRoof) { vn = vn.ParentNode; if (vn.NextSibling != null) { vn = vn.NextSibling; break; } } } } return null; } return null; } internal bool IsTextOnlyContent(XmlElement node) { Debug.Assert(FEqualIdentity(node, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS), "Invalid node type " + node.LocalName); string value = node.GetAttribute(Keywords.CONTENT); if (value == null || value.Length == 0) { string type = node.GetAttribute(Keywords.DT_TYPE, Keywords.DTNS); if (type != null && type.Length > 0) return true; return false; } if (value == Keywords.EMPTY || value == Keywords.ELTONLY || value == Keywords.ELEMENTONLY || value == Keywords.MIXED) return false; if (value == Keywords.TEXTONLY) return true; throw ExceptionBuilder.InvalidAttributeValue("content", value); } internal bool IsXDRField(XmlElement node, XmlElement typeNode) { int min = 1; int max = 1; if (!IsTextOnlyContent(typeNode)) return false; for (XmlNode n = typeNode.FirstChild; n != null; n = n.NextSibling) { if (FEqualIdentity(n, Keywords.XDR_ELEMENT, Keywords.XDRNS) || FEqualIdentity(n, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS)) return false; } if (FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS)) { GetMinMax(node, ref min, ref max); if (max == -1 || max > 1) return false; } return true; } internal DataTable HandleTable(XmlElement node) { XmlElement typeNode; Debug.Assert(FEqualIdentity(node, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS), "Invalid node type"); // Figure out if this really is a table. If not, bail out. typeNode = FindTypeNode(node); string occurs = node.GetAttribute(Keywords.MINOCCURS); if (occurs != null && occurs.Length > 0) if ((Convert.ToInt32(occurs, CultureInfo.InvariantCulture)>1) && (typeNode==null)){ return InstantiateSimpleTable(_ds, node); } occurs = node.GetAttribute(Keywords.MAXOCCURS); if (occurs != null && occurs.Length > 0) if ((string.Compare(occurs, "1" , StringComparison.Ordinal) != 0) && (typeNode==null)){ return InstantiateSimpleTable(_ds, node); } if (typeNode == null) return null; if (IsXDRField(node, typeNode)) return null; return InstantiateTable(_ds, node, typeNode); } private sealed class NameType : IComparable { public String name; public Type type; public NameType(String n, Type t) { name = n; type = t; } public int CompareTo(object obj) { return String.Compare(name, (string)obj, StringComparison.Ordinal); } }; // XDR spec: http://www.ltg.ed.ac.uk/~ht/XMLData-Reduced.htm // http://webdata/newspecs/schema/xdr_dt_schema.xml private static NameType[] mapNameTypeXdr = { new NameType("bin.base64" , typeof(Byte[]) ), /* XDR */ new NameType("bin.hex" , typeof(Byte[]) ), /* XDR */ new NameType("boolean" , typeof(bool) ), /* XDR */ new NameType("byte" , typeof(SByte) ), /* XDR */ new NameType("char" , typeof(Char) ), /* XDR */ new NameType("date" , typeof(DateTime)), /* XDR */ new NameType("dateTime" , typeof(DateTime)), /* XDR */ new NameType("dateTime.tz" , typeof(DateTime)), /* XDR */ new NameType("entities" , typeof(string) ), /* XDR */ new NameType("entity" , typeof(string) ), /* XDR */ new NameType("enumeration" , typeof(string) ), /* XDR */ new NameType("fixed.14.4" , typeof(Decimal) ), /* XDR */ new NameType("float" , typeof(Double) ), /* XDR */ new NameType("i1" , typeof(SByte) ), /* XDR */ new NameType("i2" , typeof(Int16) ), /* XDR */ new NameType("i4" , typeof(Int32) ), /* XDR */ new NameType("i8" , typeof(Int64) ), /* XDR */ new NameType("id" , typeof(string) ), /* XDR */ new NameType("idref" , typeof(string) ), /* XDR */ new NameType("idrefs" , typeof(string) ), /* XDR */ new NameType("int" , typeof(Int32) ), /* XDR */ new NameType("nmtoken" , typeof(string) ), /* XDR */ new NameType("nmtokens" , typeof(string) ), /* XDR */ new NameType("notation" , typeof(string) ), /* XDR */ new NameType("number" , typeof(Decimal) ), /* XDR */ new NameType("r4" , typeof(Single) ), /* XDR */ new NameType("r8" , typeof(Double) ), /* XDR */ new NameType("string" , typeof(string) ), /* XDR */ new NameType("time" , typeof(DateTime)), /* XDR */ new NameType("time.tz" , typeof(DateTime)), /* XDR */ new NameType("ui1" , typeof(Byte) ), /* XDR */ new NameType("ui2" , typeof(UInt16) ), /* XDR */ new NameType("ui4" , typeof(UInt32) ), /* XDR */ new NameType("ui8" , typeof(UInt64) ), /* XDR */ new NameType("uri" , typeof(string) ), /* XDR */ new NameType("uuid" , typeof(Guid) ), /* XDR */ }; private static NameType FindNameType(string name) { #if DEBUG for(int i = 1; i < mapNameTypeXdr.Length; ++i) { Debug.Assert((mapNameTypeXdr[i-1].CompareTo(mapNameTypeXdr[i].name)) < 0, "incorrect sorting"); } #endif int index = Array.BinarySearch(mapNameTypeXdr, name); if (index < 0) { #if DEBUG // Let's check that we realy don't have this name: foreach (NameType nt in mapNameTypeXdr) { Debug.Assert(nt.name != name, "FindNameType('" + name + "') -- failed. Existed name not found"); } #endif throw ExceptionBuilder.UndefinedDatatype(name); } Debug.Assert(mapNameTypeXdr[index].name == name, "FindNameType('" + name + "') -- failed. Wrong name found"); return mapNameTypeXdr[index]; } private static NameType enumerationNameType = FindNameType("enumeration"); private Type ParseDataType(string dt, string dtValues) { string strType = dt; string[] parts = dt.Split(colonArray); // ":" if (parts.Length > 2) { throw ExceptionBuilder.InvalidAttributeValue("type", dt); } else if (parts.Length == 2) { // strType = parts[1]; } NameType nt = FindNameType(strType); if (nt == enumerationNameType && (dtValues == null || dtValues.Length == 0)) throw ExceptionBuilder.MissingAttribute("type", Keywords.DT_VALUES); return nt.type; } internal string GetInstanceName(XmlElement node) { string instanceName; if (FEqualIdentity(node, Keywords.XDR_ELEMENTTYPE, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ATTRIBUTETYPE, Keywords.XDRNS)) { instanceName = node.GetAttribute(Keywords.NAME); if (instanceName == null || instanceName.Length == 0) { throw ExceptionBuilder.MissingAttribute("Element", Keywords.NAME); } } else { instanceName = node.GetAttribute(Keywords.TYPE); if (instanceName == null || instanceName.Length == 0) throw ExceptionBuilder.MissingAttribute("Element", Keywords.TYPE); } return instanceName; } internal void HandleColumn(XmlElement node, DataTable table) { Debug.Assert(FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS) || FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS), "Illegal node type"); string instanceName; string strName; Type type; string strType; string strValues; int minOccurs = 0; int maxOccurs = 1; string strDefault; DataColumn column; string strUse = node.GetAttribute(Keywords.USE); // Get the name if (node.Attributes.Count > 0) { string strRef = node.GetAttribute(Keywords.REF); if (strRef != null && strRef.Length>0) return; //skip ref nodes. B2 item strName = instanceName = GetInstanceName(node); column = table.Columns[instanceName, _schemaUri]; if (column != null) { if (column.ColumnMapping == MappingType.Attribute) { if (FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS)) throw ExceptionBuilder.DuplicateDeclaration(strName); } else { if (FEqualIdentity(node, Keywords.XDR_ELEMENT, Keywords.XDRNS)) { throw ExceptionBuilder.DuplicateDeclaration(strName); } } instanceName = GenUniqueColumnName(strName, table); } } else { strName = instanceName = ""; } // Now get the type XmlElement typeNode = FindTypeNode(node); SimpleType xsdType = null; if (typeNode == null) { strType = node.GetAttribute(Keywords.TYPE); throw ExceptionBuilder.UndefinedDatatype(strType); } strType = typeNode.GetAttribute(Keywords.DT_TYPE, Keywords.DTNS); strValues = typeNode.GetAttribute(Keywords.DT_VALUES, Keywords.DTNS); if (strType == null || strType.Length == 0) { strType = ""; type = typeof(string); } else { type = ParseDataType(strType, strValues); // if (strType == "float") { strType = ""; } if (strType == "char") { strType = ""; xsdType = SimpleType.CreateSimpleType(type); } if (strType == "enumeration") { strType = ""; xsdType = SimpleType.CreateEnumeratedType(strValues); } if (strType == "bin.base64") { strType = ""; xsdType = SimpleType.CreateByteArrayType("base64"); } if (strType == "bin.hex") { strType = ""; xsdType = SimpleType.CreateByteArrayType("hex"); } } bool isAttribute = FEqualIdentity(node, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS); GetMinMax(node, isAttribute, ref minOccurs, ref maxOccurs); strDefault = null; // Does XDR has default? strDefault = node.GetAttribute(Keywords.DEFAULT); bool bNullable = false; column = new DataColumn(XmlConvert.DecodeName(instanceName), type, null, isAttribute ? MappingType.Attribute : MappingType.Element); SetProperties(column, node.Attributes); // xmlschema.SetProperties will skipp setting expressions column.XmlDataType = strType; column.SimpleType = xsdType; column.AllowDBNull = (minOccurs == 0) || bNullable; column.Namespace = (isAttribute) ? String.Empty : _schemaUri; // webdata 97925 // We will skip handling expression columns in SetProperties, so we need set the expressions here if (node.Attributes != null) { for (int i = 0; i < node.Attributes.Count; i++) { if (node.Attributes[i].NamespaceURI == Keywords.MSDNS) { if (node.Attributes[i].LocalName == "Expression"){ column.Expression = node.Attributes[i].Value; break; } } } } String targetNamespace = node.GetAttribute(Keywords.TARGETNAMESPACE); if (targetNamespace != null && targetNamespace.Length > 0) column.Namespace = targetNamespace; table.Columns.Add(column); if (strDefault != null && strDefault.Length != 0) try { column.DefaultValue = SqlConvert.ChangeTypeForXML(strDefault, type); } catch (System.FormatException) { throw ExceptionBuilder.CannotConvert(strDefault, type.FullName); } for (XmlNode n = node.FirstChild ; n != null ; n = n.NextSibling) { if (FEqualIdentity(n, Keywords.XDR_DESCRIPTION, Keywords.XDRNS)) column.Description(((XmlElement) n).InnerText); } } internal void GetMinMax(XmlElement elNode, ref int minOccurs, ref int maxOccurs) { GetMinMax(elNode, false, ref minOccurs, ref maxOccurs); } internal void GetMinMax(XmlElement elNode, bool isAttribute, ref int minOccurs, ref int maxOccurs) { string occurs = elNode.GetAttribute(Keywords.MINOCCURS); if (occurs != null && occurs.Length > 0) { try { minOccurs = Int32.Parse(occurs, CultureInfo.InvariantCulture); } catch (Exception e) { // if (!ADP.IsCatchableExceptionType (e)) { throw; } throw ExceptionBuilder.AttributeValues("minOccurs", "0", "1"); } } occurs = elNode.GetAttribute(Keywords.MAXOCCURS); if (occurs != null && occurs.Length > 0) { int bZeroOrMore = string.Compare(occurs, Keywords.STAR , StringComparison.Ordinal); if (bZeroOrMore == 0) { maxOccurs = -1; } else { try { maxOccurs = Int32.Parse(occurs, CultureInfo.InvariantCulture); } catch (Exception e) { // if (!ADP.IsCatchableExceptionType (e)) { throw; } throw ExceptionBuilder.AttributeValues("maxOccurs", "1", Keywords.STAR); } if (maxOccurs != 1) { throw ExceptionBuilder.AttributeValues("maxOccurs", "1", Keywords.STAR); } } } } internal void HandleTypeNode(XmlElement typeNode, DataTable table, ArrayList tableChildren) { DataTable tableChild; for (XmlNode n = typeNode.FirstChild; n != null; n = n.NextSibling) { if (!(n is XmlElement)) continue; if (FEqualIdentity(n, Keywords.XDR_ELEMENT, Keywords.XDRNS)) { tableChild = HandleTable((XmlElement) n); if (tableChild != null) { tableChildren.Add(tableChild); continue; } } if (FEqualIdentity(n, Keywords.XDR_ATTRIBUTE, Keywords.XDRNS) || FEqualIdentity(n, Keywords.XDR_ELEMENT, Keywords.XDRNS)) { HandleColumn((XmlElement) n, table); continue; } } } internal DataTable InstantiateTable(DataSet dataSet, XmlElement node, XmlElement typeNode) { string typeName = ""; XmlAttributeCollection attrs = node.Attributes; DataTable table; int minOccurs = 1; int maxOccurs = 1; string keys = null; ArrayList tableChildren = new ArrayList(); if (attrs.Count > 0) { typeName = GetInstanceName(node); table = dataSet.Tables.GetTable(typeName, _schemaUri); if (table != null) { return table; } } table = new DataTable(XmlConvert.DecodeName(typeName)); // fxcop: new DataTable should inherit the CaseSensitive, Locale from DataSet and possibly updating during SetProperties table.Namespace = _schemaUri; GetMinMax(node, ref minOccurs, ref maxOccurs); table.MinOccurs = minOccurs; table.MaxOccurs = maxOccurs; _ds.Tables.Add(table); HandleTypeNode(typeNode, table, tableChildren); SetProperties(table, attrs); // check to see if we fave unique constraint if (keys != null) { string[] list = keys.TrimEnd(null).Split(null); int keyLength = list.Length; DataColumn[] cols = new DataColumn[keyLength]; for (int i = 0; i < keyLength; i++) { DataColumn col = table.Columns[list[i], _schemaUri]; if (col == null) throw ExceptionBuilder.ElementTypeNotFound(list[i]); cols[i] = col; } table.PrimaryKey = cols; } foreach(DataTable _tableChild in tableChildren) { DataRelation relation = null; DataRelationCollection childRelations = table.ChildRelations; for (int j = 0; j < childRelations.Count; j++) { if (!childRelations[j].Nested) continue; if (_tableChild == childRelations[j].ChildTable) relation = childRelations[j]; } if (relation!=null) continue; DataColumn parentKey = table.AddUniqueKey(); // foreign key in the child table DataColumn childKey = _tableChild.AddForeignKey(parentKey); // create relationship // setup relationship between parent and this table relation = new DataRelation(table.TableName + "_" + _tableChild.TableName, parentKey, childKey, true); relation.CheckMultipleNested = false; // disable the check for multiple nested parent relation.Nested = true; _tableChild.DataSet.Relations.Add(relation); relation.CheckMultipleNested = true; // enable the check for multiple nested parent } return table; } internal DataTable InstantiateSimpleTable(DataSet dataSet, XmlElement node) { string typeName; XmlAttributeCollection attrs = node.Attributes; DataTable table; int minOccurs = 1; int maxOccurs = 1; typeName = GetInstanceName(node); table = dataSet.Tables.GetTable(typeName, _schemaUri); if (table != null) { throw ExceptionBuilder.DuplicateDeclaration(typeName); } String tbName = XmlConvert.DecodeName(typeName); table = new DataTable(tbName); // fxcop: new DataTable will either inherit the CaseSensitive, Locale from DataSet or be set during SetProperties table.Namespace = _schemaUri; GetMinMax(node, ref minOccurs, ref maxOccurs); table.MinOccurs = minOccurs; table.MaxOccurs = maxOccurs; SetProperties(table, attrs); table.repeatableElement = true; HandleColumn((XmlElement) node, table); table.Columns[0].ColumnName = tbName + "_Column"; _ds.Tables.Add(table); return table; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HttpApplicationFactory.cs
- OdbcEnvironment.cs
- MetadataPropertyAttribute.cs
- CommandManager.cs
- IconConverter.cs
- ButtonColumn.cs
- RightsManagementEncryptedStream.cs
- PathData.cs
- OutputBuffer.cs
- RemoteAsymmetricSignatureFormatter.cs
- ServiceOperationParameter.cs
- NamespaceInfo.cs
- XPathMultyIterator.cs
- HttpEncoderUtility.cs
- FormatControl.cs
- SourceFileInfo.cs
- EncoderParameters.cs
- TransformValueSerializer.cs
- ResizeBehavior.cs
- ObjectDataSource.cs
- PrintControllerWithStatusDialog.cs
- TypeReference.cs
- TypeValidationEventArgs.cs
- QilChoice.cs
- UdpDiscoveryEndpointElement.cs
- SaveFileDialog.cs
- BrowserCapabilitiesFactoryBase.cs
- WebPartCatalogAddVerb.cs
- KnownTypesProvider.cs
- NumericExpr.cs
- ChannelTraceRecord.cs
- ListenerTraceUtility.cs
- ProxyAssemblyNotLoadedException.cs
- TextTreeNode.cs
- SystemBrushes.cs
- CapiSymmetricAlgorithm.cs
- TextRenderer.cs
- ProgressBarHighlightConverter.cs
- MessageQueuePermissionAttribute.cs
- ToolStripItem.cs
- FormatException.cs
- VoiceObjectToken.cs
- Transform3D.cs
- EventLogTraceListener.cs
- ResXResourceSet.cs
- SQLGuidStorage.cs
- SrgsSubset.cs
- SqlSelectClauseBuilder.cs
- SqlComparer.cs
- ButtonBase.cs
- ProcessModuleDesigner.cs
- MachineKeySection.cs
- XmlSchemaComplexType.cs
- ReachPageContentCollectionSerializer.cs
- SaveFileDialog.cs
- HTMLTextWriter.cs
- Material.cs
- ReachUIElementCollectionSerializer.cs
- DataColumn.cs
- InfoCardProofToken.cs
- UIAgentMonitorHandle.cs
- DictionaryManager.cs
- OrthographicCamera.cs
- ResXBuildProvider.cs
- CodeDirectoryCompiler.cs
- CodeGeneratorOptions.cs
- TogglePattern.cs
- Atom10FormatterFactory.cs
- LineSegment.cs
- MultipleViewProviderWrapper.cs
- TabItemAutomationPeer.cs
- TypeBrowserDialog.cs
- MemberInfoSerializationHolder.cs
- LinearGradientBrush.cs
- BinarySecretKeyIdentifierClause.cs
- NamespaceEmitter.cs
- HttpModulesInstallComponent.cs
- ContractCodeDomInfo.cs
- RequestContext.cs
- EntityParameterCollection.cs
- KeyPressEvent.cs
- WinEventQueueItem.cs
- WebBrowsableAttribute.cs
- ReferenceEqualityComparer.cs
- HitTestWithGeometryDrawingContextWalker.cs
- DelegateBodyWriter.cs
- RegexMatchCollection.cs
- ListViewItemMouseHoverEvent.cs
- FixedTextPointer.cs
- ListViewGroupConverter.cs
- ListControlConvertEventArgs.cs
- TransactionState.cs
- AllMembershipCondition.cs
- AssertSection.cs
- OletxCommittableTransaction.cs
- FileUtil.cs
- HttpModuleCollection.cs
- DataKeyCollection.cs
- QilName.cs
- DataListItem.cs