System.Data.XmlDataLoader.LoadColumn C# (CSharp) Method

LoadColumn() private method

private LoadColumn ( DataColumn column, object foundColumns ) : void
column DataColumn
foundColumns object
return void
        private void LoadColumn(DataColumn column, object[] foundColumns)
        {
            //  <DataSet>    /--------------------------------- We are here on entrance
            //      <Table> /
            //          <Column>Value</Column>
            //          <AnotherColumn>Value</AnotherColumn>
            //      </Table>    \------------------------------ We are here on exit
            //  </DataSet>

            //  <Column>                                        If we have something like this
            //      <Foo>FooVal</Foo>                           We would grab first text-like node
            //      Value                                       In this case it would be "FooVal"
            //      <Bar>BarVal</Bar>                           And not "Value" as you might think
            //  </Column>                                       This is how desktop works

            string text = string.Empty;                         // Column text. Assume empty string
            string xsiNilString = null;                         // Possible NIL attribute string

            int entryDepth = _dataReader.Depth;                  // Store depth so we won't read too much

            if (_dataReader.AttributeCount > 0)                  // If have attributes
                xsiNilString = _dataReader.GetAttribute(Keywords.XSI_NIL, Keywords.XSINS);
            // Try to get NIL attribute
            // We have to do it before we move to the next element
            if (column.IsCustomType)
            {                          // Custom type column
                object columnValue = null;                    // Column value we're after. Assume no value.

                string xsiTypeString = null;                    // XSI type name from TYPE attribute
                string typeName = null;                    // Type name from MSD_INSTANCETYPE attribute

                XmlRootAttribute xmlAttrib = null;              // Might need this attribute for XmlSerializer

                if (_dataReader.AttributeCount > 0)
                {            // If have attributes, get attributes we'll need
                    xsiTypeString = _dataReader.GetAttribute(Keywords.TYPE, Keywords.XSINS);
                    typeName = _dataReader.GetAttribute(Keywords.MSD_INSTANCETYPE, Keywords.MSDNS);
                }

                // Check if need to use XmlSerializer. We need to do that if type does not implement IXmlSerializable.
                // We also need to do that if no polymorphism for this type allowed.

                bool useXmlSerializer = !column.ImplementsIXMLSerializable &&
                    !((column.DataType == typeof(object)) || (typeName != null) || (xsiTypeString != null));

                // Check if we have an attribute telling us value is null.

                if ((xsiNilString != null) && XmlConvert.ToBoolean(xsiNilString))
                {
                    if (!useXmlSerializer)
                    {                    // See if need to set typed null.
                        if (typeName != null && typeName.Length > 0)
                        {
                            // Got type name
                            columnValue = SqlUdtStorage.GetStaticNullForUdtType(DataStorage.GetType(typeName));
                        }
                    }

                    if (null == columnValue)
                    {                  // If no value,
                        columnValue = DBNull.Value;             // change to DBNull;
                    }

                    if (!_dataReader.IsEmptyElement)           // In case element is not empty
                        while (_dataReader.Read() && (entryDepth < _dataReader.Depth)) ;
                    // Read current elements
                    _dataReader.Read();                          // And start reading next element.
                }
                else
                {                                          // No NIL attribute. Get value
                    bool skipped = false;

                    if (column.Table.DataSet != null && column.Table.DataSet._udtIsWrapped)
                    {
                        _dataReader.Read(); // if UDT is wrapped, skip the wrapper
                        skipped = true;
                    }

                    if (useXmlSerializer)
                    {                     // Create an attribute for XmlSerializer
                        if (skipped)
                        {
                            xmlAttrib = new XmlRootAttribute(_dataReader.LocalName);
                            xmlAttrib.Namespace = _dataReader.NamespaceURI;
                        }
                        else
                        {
                            xmlAttrib = new XmlRootAttribute(column.EncodedColumnName);
                            xmlAttrib.Namespace = column.Namespace;
                        }
                    }

                    columnValue = column.ConvertXmlToObject(_dataReader, xmlAttrib);
                    // Go get the value
                    if (skipped)
                    {
                        _dataReader.Read(); // if Wrapper is skipped, skip its end tag
                    }
                }

                foundColumns[column.Ordinal] = columnValue;     // Store value
            }
            else
            {                                                  // Not a custom type. 
                if (_dataReader.Read() && entryDepth < _dataReader.Depth)
                {
                    // Read to the next element and see if we're inside.
                    while (entryDepth < _dataReader.Depth)
                    {
                        switch (_dataReader.NodeType)
                        {              // Process nodes based on type
                            case XmlNodeType.Text:                      // It looks like a text. And we need it.
                            case XmlNodeType.Whitespace:
                            case XmlNodeType.CDATA:
                            case XmlNodeType.SignificantWhitespace:
                                if (0 == text.Length)
                                {                 // In case we do not have value already
                                    text = _dataReader.Value;            // Get value.

                                    // See if we have other text nodes near. In most cases this loop will not be executed. 
                                    StringBuilder builder = null;
                                    while (_dataReader.Read() && entryDepth < _dataReader.Depth && IsTextLikeNode(_dataReader.NodeType))
                                    {
                                        if (builder == null)
                                        {
                                            builder = new StringBuilder(text);
                                        }
                                        builder.Append(_dataReader.Value);  // Concatenate other sequential text like
                                                                            // nodes we might have. This is rare.
                                                                            // We're using this instead of dataReader.ReadString()
                                                                            // which would do the same thing but slower.
                                    }

                                    if (builder != null)
                                    {
                                        text = builder.ToString();
                                    }
                                }
                                else
                                {
                                    _dataReader.ReadString();            // We've got column value already. Read this one and ignore it.
                                }
                                break;
                            case XmlNodeType.Element:
                                if (ProcessXsdSchema())
                                {               // Check for schema. Skip or load if found.
                                    continue;                           // Schema has been found. Process the next element 
                                                                        // we're already at (done by schema processing).
                                }
                                else
                                {
                                    // We've got element which is not supposed to he here.
                                    // That might be table which was misplaced.
                                    // Or it might be a column inside column (also misplaced).
                                    object o = _nodeToSchemaMap.GetColumnSchema(column.Table, _dataReader, FIgnoreNamespace(_dataReader));
                                    // Get dataset element for this XML element
                                    DataColumn c = o as DataColumn;     // Perhaps, it's a column?

                                    if (c != null)
                                    {                  // Do we have matched column in this table?
                                                       // Let's load column data

                                        if (foundColumns[c.Ordinal] == null)
                                        {
                                            // If this column was not found before
                                            LoadColumn(c, foundColumns);
                                            // Get column value
                                        }
                                        else
                                        {
                                            _dataReader.Read();          // Already loaded, proceed to the next element
                                        }
                                    }
                                    else
                                    {
                                        DataTable nestedTable = o as DataTable;
                                        // Perhaps, it's a nested table ?
                                        if (nestedTable != null)
                                        {
                                            // Do we have matched table in DataSet ?
                                            LoadTable(nestedTable, true /* isNested */);
                                            // Yes. Load nested table (recursive)
                                        }
                                        else
                                        {                          // Not a nested column nor nested table.    
                                                                   // Let's try other tables in the DataSet

                                            DataTable misplacedTable = _nodeToSchemaMap.GetTableForNode(_dataReader, FIgnoreNamespace(_dataReader));
                                            // Try to get table for node
                                            if (misplacedTable != null)
                                            {
                                                // Got some table to match?
                                                LoadTable(misplacedTable, false /* isNested */);
                                                // While table's XML element is nested,
                                                // the table itself is not. Load it this way.
                                            }
                                            else
                                            {
                                                _dataReader.Read();      // No match? Try next element
                                            }
                                        }
                                    }
                                }
                                break;
                            case XmlNodeType.EntityReference:           // Oops. No support for Entity Reference
                                throw ExceptionBuilder.FoundEntity();
                            default:
                                _dataReader.Read();                      // We don't process that, skip to the next element.
                                break;
                        }
                    }

                    _dataReader.Read();                              // We're done here. To the next element.
                }

                if (0 == text.Length && xsiNilString != null && XmlConvert.ToBoolean(xsiNilString))
                {
                    foundColumns[column.Ordinal] = DBNull.Value;
                    // If no data and NIL attribute is true set value to null
                }
                else
                {
                    foundColumns[column.Ordinal] = column.ConvertXmlToObject(text);
                }
            }
        }