Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / XmlDataLoader.cs / 2 / XmlDataLoader.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Collections; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Text; using System.Xml; using System.Xml.Serialization; internal sealed class XmlDataLoader { DataSet dataSet; XmlToDatasetMap nodeToSchemaMap = null; Hashtable nodeToRowMap; Stack childRowsStack = null; Hashtable htableExcludedNS = null; bool fIsXdr = false; internal bool isDiffgram = false; DataRow topMostRow = null; XmlElement topMostNode = null; bool ignoreSchema = false; DataTable dataTable; bool isTableLevel = false; private bool fromInference = false; internal XmlDataLoader( DataSet dataset, bool IsXdr, bool ignoreSchema) { // Initialization this.dataSet = dataset; this.nodeToRowMap = new Hashtable(); this.fIsXdr = IsXdr; this.ignoreSchema = ignoreSchema; } internal XmlDataLoader( DataSet dataset, bool IsXdr, XmlElement topNode, bool ignoreSchema) { // Initialization this.dataSet = dataset; this.nodeToRowMap = new Hashtable(); this.fIsXdr = IsXdr; // Allocate the stack and create the mappings childRowsStack = new Stack(50); topMostNode = topNode; this.ignoreSchema = ignoreSchema; } internal XmlDataLoader( DataTable datatable, bool IsXdr, bool ignoreSchema) { // Initialization this.dataSet = null; dataTable = datatable; isTableLevel = true; this.nodeToRowMap = new Hashtable(); this.fIsXdr = IsXdr; this.ignoreSchema = ignoreSchema; } internal XmlDataLoader( DataTable datatable, bool IsXdr, XmlElement topNode, bool ignoreSchema) { // Initialization this.dataSet = null; dataTable = datatable; isTableLevel = true; this.nodeToRowMap = new Hashtable(); this.fIsXdr = IsXdr; // Allocate the stack and create the mappings childRowsStack = new Stack(50); topMostNode = topNode; this.ignoreSchema = ignoreSchema; } internal bool FromInference { get { return fromInference; } set { fromInference = value; } } // after loading, all detached DataRows are attached to their tables private void AttachRows( DataRow parentRow, XmlNode parentElement ) { if (parentElement == null) return; for (XmlNode n = parentElement.FirstChild; n != null; n = n.NextSibling) { if (n.NodeType == XmlNodeType.Element) { XmlElement e = (XmlElement) n; DataRow r = GetRowFromElement( e ); if (r != null && r.RowState == DataRowState.Detached) { if (parentRow != null) r.SetNestedParentRow( parentRow, /*setNonNested*/ false ); r.Table.Rows.Add( r ); } else if (r == null) { // n is a 'sugar element' AttachRows( parentRow, n ); } // attach all detached rows AttachRows( r, n ); } } } private int CountNonNSAttributes (XmlNode node) { int count = 0; for (int i = 0; i < node.Attributes.Count; i++) { XmlAttribute attr = node.Attributes[i]; if (!FExcludedNamespace(node.Attributes[i].NamespaceURI)) count++; } return count; } private string GetValueForTextOnlyColums( XmlNode n ) { string value = null; // don't consider whitespace while (n != null && (n.NodeType == XmlNodeType.Whitespace || !IsTextLikeNode(n.NodeType))) { n = n.NextSibling; } if (n != null) { if (IsTextLikeNode( n.NodeType ) && (n.NextSibling == null || !IsTextLikeNode( n.NodeType ))) { // don't use string builder if only one text node exists value = n.Value; n = n.NextSibling; } else { StringBuilder sb = new StringBuilder(); while (n != null && IsTextLikeNode( n.NodeType )) { sb.Append( n.Value ); n = n.NextSibling; } value = sb.ToString(); } } if (value == null) value = String.Empty; return value; } private string GetInitialTextFromNodes( ref XmlNode n ) { string value = null; if (n != null) { // don't consider whitespace while (n.NodeType == XmlNodeType.Whitespace) n = n.NextSibling; if (IsTextLikeNode( n.NodeType ) && (n.NextSibling == null || !IsTextLikeNode( n.NodeType ))) { // don't use string builder if only one text node exists value = n.Value; n = n.NextSibling; } else { StringBuilder sb = new StringBuilder(); while (n != null && IsTextLikeNode( n.NodeType )) { sb.Append( n.Value ); n = n.NextSibling; } value = sb.ToString(); } } if (value == null) value = String.Empty; return value; } private DataColumn GetTextOnlyColumn( DataRow row ) { DataColumnCollection columns = row.Table.Columns; int cCols = columns.Count; for (int iCol = 0; iCol < cCols; iCol++) { DataColumn c = columns[iCol]; if (IsTextOnly( c )) return c; } return null; } internal DataRow GetRowFromElement( XmlElement e ) { return(DataRow) nodeToRowMap[e]; } internal bool FColumnElement(XmlElement e) { if (nodeToSchemaMap.GetColumnSchema(e, FIgnoreNamespace(e)) == null) return false; if (CountNonNSAttributes(e) > 0) return false; for (XmlNode tabNode = e.FirstChild; tabNode != null; tabNode = tabNode.NextSibling) if (tabNode is XmlElement) return false; return true; } private bool FExcludedNamespace(string ns) { if (ns.Equals(Keywords.XSD_XMLNS_NS)) return true; if (htableExcludedNS == null) return false; return htableExcludedNS.Contains(ns); } private bool FIgnoreNamespace(XmlNode node) { XmlNode ownerNode; if (!fIsXdr) return false; if (node is XmlAttribute) ownerNode = ((XmlAttribute)node).OwnerElement; else ownerNode = node; if (ownerNode.NamespaceURI.StartsWith("x-schema:#", StringComparison.Ordinal)) return true; else return false; } private bool FIgnoreNamespace(XmlReader node) { if (fIsXdr && node.NamespaceURI.StartsWith("x-schema:#", StringComparison.Ordinal)) return true; else return false; } internal bool IsTextLikeNode( XmlNodeType n ) { switch (n) { case XmlNodeType.EntityReference: throw ExceptionBuilder.FoundEntity(); case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: case XmlNodeType.CDATA: return true; default: return false; } } internal bool IsTextOnly( DataColumn c ) { if (c.ColumnMapping != MappingType.SimpleContent) return false; else return true; } internal void LoadData( XmlDocument xdoc ) { if (xdoc.DocumentElement == null) return; bool saveEnforce; if (isTableLevel) { saveEnforce = dataTable.EnforceConstraints; dataTable.EnforceConstraints = false; } else { saveEnforce = dataSet.EnforceConstraints; dataSet.EnforceConstraints = false; dataSet.fInReadXml = true; } if (isTableLevel) { nodeToSchemaMap = new XmlToDatasetMap(dataTable, xdoc.NameTable); } else { nodeToSchemaMap = new XmlToDatasetMap(dataSet, xdoc.NameTable); } /* // Top level table or dataset ? XmlElement rootElement = xdoc.DocumentElement; Hashtable tableAtoms = new Hashtable(); XmlNode tabNode; if (CountNonNSAttributes (rootElement) > 0) dataSet.fTopLevelTable = true; else { for (tabNode = rootElement.FirstChild; tabNode != null; tabNode = tabNode.NextSibling) { if (tabNode is XmlElement && tabNode.LocalName != Keywords.XSD_SCHEMA) { object value = tableAtoms[QualifiedName (tabNode.LocalName, tabNode.NamespaceURI)]; if (value == null || (bool)value == false) { dataSet.fTopLevelTable = true; break; } } } } */ DataRow topRow = null; if (isTableLevel ||(dataSet!= null && dataSet.fTopLevelTable) ){ XmlElement e = xdoc.DocumentElement; DataTable topTable = (DataTable) nodeToSchemaMap.GetSchemaForNode(e, FIgnoreNamespace(e)); if (topTable != null) { topRow = topTable.CreateEmptyRow(); //[....] perf nodeToRowMap[ e ] = topRow; // get all field values. LoadRowData( topRow, e ); topTable.Rows.Add(topRow); } } LoadRows( topRow, xdoc.DocumentElement ); AttachRows( topRow, xdoc.DocumentElement ); if (isTableLevel) { dataTable.EnforceConstraints = saveEnforce; } else { dataSet.fInReadXml = false; dataSet.EnforceConstraints = saveEnforce; } } private void LoadRowData(DataRow row, XmlElement rowElement) { XmlNode n; DataTable table = row.Table; if (FromInference) table.Prefix = rowElement.Prefix; // keep a list of all columns that get updated Hashtable foundColumns = new Hashtable(); row.BeginEdit(); // examine all children first n = rowElement.FirstChild; // Look for data to fill the TextOnly column DataColumn column = GetTextOnlyColumn( row ); if (column != null) { foundColumns[column] = column; string text = GetValueForTextOnlyColums( n ) ; if (XMLSchema.GetBooleanAttribute(rowElement, Keywords.XSI_NIL, Keywords.XSINS, false) && Common.ADP.IsEmpty(text) ) row[column] = DBNull.Value; else SetRowValueFromXmlText( row, column, text ); } // Walk the region to find elements that map to columns while (n != null && n != rowElement) { if (n.NodeType == XmlNodeType.Element) { XmlElement e = (XmlElement) n; object schema = nodeToSchemaMap.GetSchemaForNode( e, FIgnoreNamespace(e) ); if (schema is DataTable) { if (FColumnElement(e)) schema = nodeToSchemaMap.GetColumnSchema( e, FIgnoreNamespace(e) ); } // if element has its own table mapping, it is a separate region if (schema == null || schema is DataColumn) { // descend to examine child elements n = e.FirstChild; if (schema != null && schema is DataColumn) { DataColumn c = (DataColumn) schema; if (c.Table == row.Table && c.ColumnMapping != MappingType.Attribute && foundColumns[c] == null) { foundColumns[c] = c; string text = GetValueForTextOnlyColums( n ) ; if (XMLSchema.GetBooleanAttribute(e, Keywords.XSI_NIL, Keywords.XSINS, false) && Common.ADP.IsEmpty(text) ) row[c] = DBNull.Value; else SetRowValueFromXmlText( row, c, text ); } } else if ((schema == null) && (n!=null)) { continue; } // nothing left down here, continue from element if (n == null) n = e; } } // if no more siblings, ascend back toward original element (rowElement) while (n != rowElement && n.NextSibling == null) { n = n.ParentNode; } if (n != rowElement) n = n.NextSibling; } // // Walk the attributes to find attributes that map to columns. // foreach( XmlAttribute attr in rowElement.Attributes ) { object schema = nodeToSchemaMap.GetColumnSchema( attr, FIgnoreNamespace(attr) ); if (schema != null && schema is DataColumn) { DataColumn c = (DataColumn) schema; if (c.ColumnMapping == MappingType.Attribute && foundColumns[c] == null) { foundColumns[c] = c; n = attr.FirstChild; SetRowValueFromXmlText( row, c, GetInitialTextFromNodes( ref n ) ); } } } // Null all columns values that aren't represented in the tree foreach( DataColumn c in row.Table.Columns ) { if (foundColumns[c] == null && XmlToDatasetMap.IsMappedColumn(c)) { if (!c.AutoIncrement) { if (c.AllowDBNull) { row[c] = DBNull.Value; } else { row[c] = c.DefaultValue; } } else { c.Init(row.tempRecord); } } } row.EndEdit(); } // load all data from tree structre into datarows private void LoadRows( DataRow parentRow, XmlNode parentElement ) { if (parentElement == null) return; // Skip schema node as well if (parentElement.LocalName == Keywords.XSD_SCHEMA && parentElement.NamespaceURI == Keywords.XSDNS || parentElement.LocalName == Keywords.SQL_SYNC && parentElement.NamespaceURI == Keywords.UPDGNS || parentElement.LocalName == Keywords.XDR_SCHEMA && parentElement.NamespaceURI == Keywords.XDRNS) return; for (XmlNode n = parentElement.FirstChild; n != null; n = n.NextSibling) { if (n is XmlElement) { XmlElement e = (XmlElement) n; object schema = nodeToSchemaMap.GetSchemaForNode( e, FIgnoreNamespace(e) ); if (schema != null && schema is DataTable) { DataRow r = GetRowFromElement( e ); if (r == null) { // skip columns which has the same name as another table if (parentRow != null && FColumnElement(e)) continue; r = ((DataTable)schema).CreateEmptyRow(); nodeToRowMap[ e ] = r; // get all field values. LoadRowData( r, e ); } // recurse down to inner elements LoadRows( r, n ); } else { // recurse down to inner elements LoadRows( null, n ); } } } } private void SetRowValueFromXmlText( DataRow row, DataColumn col, string xmlText ) { row[col] = col.ConvertXmlToObject(xmlText); } internal void LoadTopMostRow(ref bool[] foundColumns) { // Attempt to load row from top node we backed up in DataSet.ReadXml() // In most cases it contains the DataSet name and no information // Check if DataSet object matches the top node (it won't in most cases) Object obj = nodeToSchemaMap.GetSchemaForNode(topMostNode,FIgnoreNamespace(topMostNode)); if (obj is DataTable) { // It's a table? Load it. DataTable table = (DataTable) obj; topMostRow = table.CreateEmptyRow(); foundColumns = new bool[topMostRow.Table.Columns.Count]; // // Walk the attributes to find attributes that map to columns. // foreach( XmlAttribute attr in topMostNode.Attributes ) { object schema = nodeToSchemaMap.GetColumnSchema( attr, FIgnoreNamespace(attr) ); if (schema != null && schema is DataColumn) { DataColumn c = (DataColumn) schema; if (c.ColumnMapping == MappingType.Attribute) { XmlNode n = attr.FirstChild; SetRowValueFromXmlText( topMostRow, c, GetInitialTextFromNodes( ref n ) ); foundColumns[c.Ordinal] = true; } } } } topMostNode = null; } private XmlReader dataReader = null; private object XSD_XMLNS_NS; private object XDR_SCHEMA; private object XDRNS; private object SQL_SYNC; private object UPDGNS; private object XSD_SCHEMA; private object XSDNS; private object DFFNS; private object MSDNS; private object DIFFID; private object HASCHANGES; private object ROWORDER; private void InitNameTable() { XmlNameTable nameTable = dataReader.NameTable; XSD_XMLNS_NS = nameTable.Add(Keywords.XSD_XMLNS_NS); XDR_SCHEMA = nameTable.Add(Keywords.XDR_SCHEMA); XDRNS = nameTable.Add(Keywords.XDRNS); SQL_SYNC = nameTable.Add(Keywords.SQL_SYNC); UPDGNS = nameTable.Add(Keywords.UPDGNS); XSD_SCHEMA = nameTable.Add(Keywords.XSD_SCHEMA); XSDNS = nameTable.Add(Keywords.XSDNS); DFFNS = nameTable.Add(Keywords.DFFNS); MSDNS = nameTable.Add(Keywords.MSDNS); DIFFID = nameTable.Add(Keywords.DIFFID); HASCHANGES = nameTable.Add(Keywords.HASCHANGES); ROWORDER = nameTable.Add(Keywords.ROWORDER); } internal void LoadData(XmlReader reader) { dataReader = DataTextReader.CreateReader(reader); int entryDepth = dataReader.Depth; // Store current XML element depth so we'll read // correct portion of the XML and no more bool fEnforce = isTableLevel ? dataTable.EnforceConstraints : dataSet.EnforceConstraints; // Keep constraints status for datataset/table InitNameTable(); // Adds DataSet namespaces to reader's nametable if (nodeToSchemaMap == null) { // Create XML to dataset map nodeToSchemaMap = isTableLevel ? new XmlToDatasetMap(dataReader.NameTable, dataTable) : new XmlToDatasetMap(dataReader.NameTable, dataSet); } if (isTableLevel) { dataTable.EnforceConstraints = false; // Disable constraints } else { dataSet.EnforceConstraints = false; // Disable constraints dataSet.fInReadXml = true; // We're in ReadXml now } if (topMostNode != null) { // Do we have top node? if (!isDiffgram && !isTableLevel) { // Not a diffgram and not DataSet? DataTable table = nodeToSchemaMap.GetSchemaForNode(topMostNode, FIgnoreNamespace(topMostNode)) as DataTable; // Try to match table in the dataset to this node if (table != null) { // Got the table ? LoadTopMostTable(table); // Load top most node } } topMostNode = null; // topMostNode is no more. Good riddance. } while( !dataReader.EOF ) { // Main XML parsing loop. Check for EOF just in case. if (dataReader.Depth < entryDepth) // Stop if we have consumed all elements allowed break; if ( reader.NodeType != XmlNodeType.Element ) { // Read till Element is found dataReader.Read(); continue; } DataTable table = nodeToSchemaMap.GetTableForNode(dataReader, FIgnoreNamespace(dataReader)); // Try to get table for node if (table == null) { // Read till table is found if (!ProcessXsdSchema()) // Check for schemas... dataReader.Read(); // Not found? Read next element. continue; } LoadTable(table, false /* isNested */); // Here goes -- load data for this table // This is a root table, so it's not nested } if (isTableLevel) { dataTable.EnforceConstraints = fEnforce; // Restore constraints and return } else { dataSet.fInReadXml = false; // We're done. dataSet.EnforceConstraints = fEnforce; // Restore constraints and return } } // Loads a top most table. // This is neded because desktop is capable of loading almost anything into the dataset. // The top node could be a DataSet element or a Table element. To make things worse, // you could have a table with the same name as dataset. // Here's how we're going to dig into this mess: // // TopNode is null ? // / No \ Yes // Table matches TopNode ? Current node is the table start // / No \ Yes (LoadTopMostTable called in this case only) // Current node is the table start DataSet name matches one of the tables ? // TopNode is dataset node / Yes \ No // / TopNode is the table // Current node matches column or nested table in the table ? and current node // / No \ Yes is a column or a // TopNode is DataSet TopNode is table nested table // // Yes, it is terrible and I don't like it also.. private void LoadTopMostTable(DataTable table) { // /------------------------------- This one is in topMostNode (backed up to XML DOM) //
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ParenthesizePropertyNameAttribute.cs
- CutCopyPasteHelper.cs
- MappedMetaModel.cs
- LockedBorderGlyph.cs
- UnknownWrapper.cs
- ProbeMatchesApril2005.cs
- AuthenticatingEventArgs.cs
- StatusBarPanelClickEvent.cs
- TextHidden.cs
- InputReferenceExpression.cs
- NameTable.cs
- HttpTransportSecurity.cs
- SimpleBitVector32.cs
- HotSpotCollectionEditor.cs
- AlternationConverter.cs
- MergeFilterQuery.cs
- IdentityNotMappedException.cs
- DefaultTextStoreTextComposition.cs
- SByteStorage.cs
- FreeFormPanel.cs
- Point4DConverter.cs
- ProcessModelSection.cs
- dataSvcMapFileLoader.cs
- NeutralResourcesLanguageAttribute.cs
- HostSecurityManager.cs
- _UriTypeConverter.cs
- X509Extension.cs
- PartManifestEntry.cs
- OleDbInfoMessageEvent.cs
- FixedSOMPage.cs
- ScriptModule.cs
- SelectionEditor.cs
- StoreItemCollection.Loader.cs
- DbConnectionFactory.cs
- RootBrowserWindowProxy.cs
- QueryContinueDragEvent.cs
- UmAlQuraCalendar.cs
- ServiceEndpoint.cs
- WindowsFormsHelpers.cs
- HelpKeywordAttribute.cs
- QilDataSource.cs
- DirectoryInfo.cs
- IODescriptionAttribute.cs
- Rectangle.cs
- DesignerObject.cs
- PageHandlerFactory.cs
- EDesignUtil.cs
- GenericEnumerator.cs
- ItemMap.cs
- WebUtil.cs
- StringFunctions.cs
- Bezier.cs
- Attributes.cs
- XmlUTF8TextReader.cs
- ExecutionContext.cs
- WebPartCancelEventArgs.cs
- RestHandler.cs
- CodeTypeMember.cs
- PerCallInstanceContextProvider.cs
- DataContractSet.cs
- Parameter.cs
- NamedElement.cs
- HwndMouseInputProvider.cs
- DbXmlEnabledProviderManifest.cs
- IsolatedStoragePermission.cs
- Run.cs
- RankException.cs
- NoClickablePointException.cs
- SessionParameter.cs
- RemotingConfigParser.cs
- QuaternionAnimation.cs
- LogExtentCollection.cs
- RightsManagementEncryptionTransform.cs
- PlatformNotSupportedException.cs
- StrokeFIndices.cs
- PackageRelationshipSelector.cs
- CommonDialog.cs
- DiscoveryDocumentSerializer.cs
- FileEnumerator.cs
- AuthorizationRuleCollection.cs
- DataSourceSelectArguments.cs
- ByteStreamMessageUtility.cs
- SQlBooleanStorage.cs
- CompilerScopeManager.cs
- DesignerRegionMouseEventArgs.cs
- DebugControllerThread.cs
- ICollection.cs
- WebPartDescription.cs
- ChangePasswordDesigner.cs
- MobileUserControlDesigner.cs
- PerformanceCountersElement.cs
- XsdBuildProvider.cs
- WebDisplayNameAttribute.cs
- SqlRemoveConstantOrderBy.cs
- GroupJoinQueryOperator.cs
- AuthenticationService.cs
- DesignerAttributeInfo.cs
- Listbox.cs
- Visitors.cs
- _Rfc2616CacheValidators.cs