Example #1
0
        private void AddRowToTable(XmlNode tableNode, DataColumn relationColumn, bool inferSchema, bool fillRows)
        {
            Hashtable rowValue = new Hashtable();
            DataTable table;

            // Check if the table exists in the DataSet. If not create one.
            if (DSet.Tables.Contains(tableNode.LocalName))
            {
                table = DSet.Tables[tableNode.LocalName];
            }
            else if (inferSchema)
            {
                table = new DataTable(tableNode.LocalName);
                DSet.Tables.Add(table);
            }
            else
            {
                return;
            }

            // For elements that are inferred as tables and that contain text
            // but have no child elements, a new column named "TableName_Text"
            // is created for the text of each of the elements.
            // If an element is inferred as a table and has text, but also has child elements,
            // the text is ignored.
            // Note : if an element is inferred as a table and has text
            // and has no child elements,
            // but the repeated ements of this table have child elements,
            // then the text is ignored.
            if (!HaveChildElements(tableNode) && HaveText(tableNode) &&
                !IsRepeatedHaveChildNodes(tableNode))
            {
                string columnName = tableNode.Name + "_Text";
                if (!table.Columns.Contains(columnName))
                {
                    table.Columns.Add(columnName);
                }
                rowValue.Add(columnName, tableNode.InnerText);
            }

            // Get the child nodes of the table. Any child can be one of the following tow:
            // 1. DataTable - if there was a relation with another table..
            // 2. DataColumn - column of the current table.
            XmlNodeList childList = tableNode.ChildNodes;

            for (int i = 0; i < childList.Count; i++)
            {
                XmlNode childNode = childList[i];

                // we are looping through elements only
                // Note : if an element is inferred as a table and has text, but also has child elements,
                // the text is ignored.
                if (childNode.NodeType != XmlNodeType.Element)
                {
                    continue;
                }

                // Elements that have attributes are inferred as tables.
                // Elements that have child elements are inferred as tables.
                // Elements that repeat are inferred as a single table.
                if (IsInferredAsTable(childNode))
                {
                    // child node inferred as table
                    if (inferSchema)
                    {
                        // We need to create new column for the relation between the current
                        // table and the new table we found (the child table).
                        string newRelationColumnName = table.TableName + "_Id";
                        if (!table.Columns.Contains(newRelationColumnName))
                        {
                            DataColumn newRelationColumn = new DataColumn(newRelationColumnName, typeof(int));
                            newRelationColumn.AllowDBNull   = false;
                            newRelationColumn.AutoIncrement = true;
                            // we do not want to serialize this column so MappingType is Hidden.
                            newRelationColumn.ColumnMapping = MappingType.Hidden;
                            table.Columns.Add(newRelationColumn);
                        }
                        // Add a row to the new table we found.
                        AddRowToTable(childNode, table.Columns[newRelationColumnName], inferSchema, fillRows);
                    }
                    else
                    {
                        AddRowToTable(childNode, null, inferSchema, fillRows);
                    }
                }
                else
                {
                    // Elements that have no attributes or child elements, and do not repeat,
                    // are inferred as columns.
                    object val = null;
                    if (childNode.FirstChild != null)
                    {
                        val = childNode.FirstChild.Value;
                    }
                    else
                    {
                        val = "";
                    }
                    if (table.Columns.Contains(childNode.LocalName))
                    {
                        rowValue.Add(childNode.LocalName, val);
                    }
                    else if (inferSchema)
                    {
                        table.Columns.Add(childNode.LocalName);
                        rowValue.Add(childNode.LocalName, val);
                    }
                }
            }

            // Column can be attribute of the table element.
            XmlAttributeCollection aCollection = tableNode.Attributes;

            for (int i = 0; i < aCollection.Count; i++)
            {
                XmlAttribute attr = aCollection[i];
                //the atrribute can be the namespace.
                if (attr.Prefix.Equals("xmlns"))
                {
                    table.Namespace = attr.Value;
                }
                else // the attribute is a column.
                {
                    if (!table.Columns.Contains(attr.LocalName))
                    {
                        DataColumn col = table.Columns.Add(attr.LocalName);
                        col.ColumnMapping = MappingType.Attribute;
                    }
                    table.Columns[attr.LocalName].Namespace = table.Namespace;

                    rowValue.Add(attr.LocalName, attr.Value);
                }
            }

            // If the current table is a child table we need to add a new column for the relation
            // and add a new relation to the DataSet.
            if (relationColumn != null)
            {
                if (!table.Columns.Contains(relationColumn.ColumnName))
                {
                    DataColumn dc = new DataColumn(relationColumn.ColumnName, typeof(int));
                    // we do not want to serialize this column so MappingType is Hidden.
                    dc.ColumnMapping = MappingType.Hidden;
                    table.Columns.Add(dc);
                    // Convention of relation name is: ParentTableName_ChildTableName
                    DataRelation dr = new DataRelation(relationColumn.Table.TableName + "_" + dc.Table.TableName, relationColumn, dc);
                    dr.Nested = true;
                    DSet.Relations.Add(dr);
                    UniqueConstraint.SetAsPrimaryKey(dr.ParentTable.Constraints, dr.ParentKeyConstraint);
                }
                rowValue.Add(relationColumn.ColumnName, relationColumn.GetAutoIncrementValue());
            }

            // Create new row and add all values to the row.
            // then add it to the table.
            DataRow row = table.NewRow();

            IDictionaryEnumerator enumerator = rowValue.GetEnumerator();

            while (enumerator.MoveNext())
            {
                row [enumerator.Key.ToString()] = StringToObject(table.Columns[enumerator.Key.ToString()].DataType, enumerator.Value.ToString());
            }

            if (fillRows)
            {
                table.Rows.Add(row);
            }
        }