?
Solved

Generate XML from hash table

Posted on 2010-11-17
16
Medium Priority
?
2,114 Views
Last Modified: 2012-05-10
Hello again experts,

I am facing a problem.

I have a grid where the selected values are trasposed to a hash table in c#

           
CheckBox chk = (CheckBox)item.FindControl("CheckBox1");
            if (chk.Checked)
            {
                var dataTable = new DataTable("Cart_Items");

                dataTable.Columns.Add("Product_ID");
                dataTable.Columns.Add("ProductName");
                dataTable.Columns.Add("ProductDesc");
                dataTable.Columns.Add("Qty");
                dataTable.Columns.Add("Currency");
                dataTable.Columns.Add("ProductPrice");

                foreach (GridDataItem gridDataItem in RadGrid1.SelectedItems)
                {
                    var hashtable = new Hashtable();
                    gridDataItem.ExtractValues(hashtable);

                    DataRow dataRow = dataTable.NewRow();
                    foreach (DictionaryEntry entry in hashtable)
                    {
                        dataRow[entry.Key.ToString()] = entry.Value;
                    }
                    dataTable.Rows.Add(dataRow);
                }

Open in new window

I then need to check to see it the file exists::
                
if (!File.Exists(Server.MapPath("~/App_Data/XML") + "\\cart.xml"))
                {

                    XmlTextWriter textWritter = new XmlTextWriter(Server.MapPath("~/App_Data/XML") + "\\cart.xml", null);
                    textWritter.WriteStartDocument();
                    textWritter.WriteStartElement("Orders");
                    textWritter.WriteEndElement();

                    textWritter.Close();
                }

Open in new window

then I need to write the contents of the hash table to the xml file in the following format
<Orders OrderID="" CustomerID="" OrderDate="" PaymentAprroved="" PaymentMethod="" PaymentAmount="" Recurring="" Frequecy="">
  <OrderItems ProductID="0" OrderID="" ProductName="ArcGIS Video - Introductory" ProductDesc="ArcGIS Video - Introductory" Qty="1" Currency="AUD" ProductPrice="600"/>
</Orders>

Open in new window


how can I acheive this???
0
Comment
Question by:XGIS
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 7
16 Comments
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 34162457
By HashTable you mean DataTable if I am not wrong?
0
 
LVL 7

Author Comment

by:XGIS
ID: 34162810
By HashTable you mean DataTable if I am not wrong?

No I mean a Hashtable....
A data table works more like a hash table, but there is a lot more overhead.
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 34163246
I was just asking because you had a datatable as well with the required data it seems and it would be easier to export from there.

Anyway, we can pretty easily create the XML from HashTable, we would typically need to iterate through all the data in the HashTable and do that manually.

Looks like you are using RADControls DataGrid, and you load the HashTable using the line
gridDataItem.ExtractValues(hashtable);

Can you tell how the data is stored in the HashTable after this line executes, I can post some code then to create the XML
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 7

Author Comment

by:XGIS
ID: 34169058
hello arif_eqbal,
i am unsure of the question that you asking.... yes I am using RadGrid and the selected values get extracted from the grid and stored in a hash table that is stored in memory until the next button is clicked.
0
 
LVL 19

Accepted Solution

by:
arif_eqbal earned 2000 total points
ID: 34170534
I just wanted to know the Key/Value content of the hashtable, but looking at your code I can guess thatthe HashTable contains only one row at a time, and each column is the key of the hashTable assuming this I am giving you a solution

Another missing item is the Order, in your XML I can see the root node as Orders with attributes like OrderID, CustomerID etc. I am assuming you have already built that Node (If not you can try and create the Node just the way we create OrderItem nodes below)

Create a Format String like this (this is your entire node without the data, we will replace the placeholders {0} {1} etc. with actual values within the loop)

string xml = @"<OrderItems ProductID=""{0}"" OrderID=""{1}"" ProductName=""{2}"" ProductDesc=""{3}"" Qty=""{4}"" Currency=""{5}"" ProductPrice=""{6}""/>";

Now modify your loop to add the last two lines as shown below:

 foreach (GridDataItem gridDataItem in RadGrid1.SelectedItems)
                {
                    var hashtable = new Hashtable();
                    gridDataItem.ExtractValues(hashtable);

                    DataRow dataRow = dataTable.NewRow();
                    foreach (DictionaryEntry entry in hashtable)
                    {
                        dataRow[entry.Key.ToString()] = entry.Value;
                    }
                    dataTable.Rows.Add(dataRow);
                   //Code to generate XML
                   XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["Qty"].ToString(), hashtable["Currency"].ToString(), hashtable["ProductPrice"].ToString()));
                   Orders.Add(prod);
                }

If you look at the last two lines the first line creates a node which is added to the root "Orders" element. Now for that you must create the Orders Element before this loop.
0
 
LVL 7

Author Comment

by:XGIS
ID: 34170771
cool thanks so is the following correct??
    protected void Button1_Click(object sender, EventArgs e)
    {
        foreach (GridDataItem item in RadGrid1.MasterTableView.Items)
        {
            CheckBox chk = (CheckBox)item.FindControl("CheckBox1");
            if (chk.Checked)
            {
                if (!File.Exists(Server.MapPath("~/App_Data/XML") + "\\cart.xml"))
                {

                    XmlTextWriter textWritter = new XmlTextWriter(Server.MapPath("~/App_Data/XML") + "\\cart.xml", null);
                    textWritter.WriteStartDocument();
                    textWritter.WriteStartElement("Orders");
                    textWritter.WriteEndElement();

                    textWritter.Close();
                }

                string xml = @"<OrderItems ProductID=""{0}"" OrderID=""{1}"" ProductName=""{2}"" ProductDesc=""{3}"" Qty=""{4}"" Currency=""{5}"" ProductPrice=""{6}""/>";

                var dataTable = new DataTable("Cart_Items");

                dataTable.Columns.Add("Product_ID");
                dataTable.Columns.Add("ProductName");
                dataTable.Columns.Add("ProductDesc");
                dataTable.Columns.Add("Qty");
                dataTable.Columns.Add("Currency");
                dataTable.Columns.Add("ProductPrice");


                foreach (GridDataItem gridDataItem in RadGrid1.SelectedItems)
                {
                    var hashtable = new Hashtable();
                    gridDataItem.ExtractValues(hashtable);

                    DataRow dataRow = dataTable.NewRow();
                    foreach (DictionaryEntry entry in hashtable)
                    {
                        dataRow[entry.Key.ToString()] = entry.Value;
                    }
                    dataTable.Rows.Add(dataRow);
                    //Code to generate XML
                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["Qty"].ToString(), hashtable["Currency"].ToString(), hashtable["ProductPrice"].ToString()));
                    Orders.Add(prod);
                }
                xmlDoc.Save(Server.MapPath("~/App_Data/XML") + "\\cart.xml");
            }
        }
    }

Open in new window

0
 
LVL 19

Assisted Solution

by:arif_eqbal
arif_eqbal earned 2000 total points
ID: 34170796
Looks like it should be ok
xmlDoc and Orders objects need to be properly created and xmlDoc would have Orders as its element.
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 34170797
Looks like it should be ok
xmlDoc and Orders objects need to be properly created and xmlDoc would have Orders as its element.
0
 
LVL 7

Author Closing Comment

by:XGIS
ID: 34170934
Wonderful thank you so much
0
 
LVL 7

Author Comment

by:XGIS
ID: 34171056
Sorry to bother you I am having a weired error::
Server Error in '/XGISAustralia' Application.
--------------------------------------------------------------------------------

Token EndDocument in state Document would result in an invalid XML document.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Token EndDocument in state Document would result in an invalid XML document.

Source Error:


Line 127:                    Orders.Add(prod);
Line 128:                }
Line 129:                Orders.Save(Server.MapPath("~/App_Data/XML") + "\\Orders.xml");
Line 130:            }
Line 131:        }
 

Source File: e:\Projects\Development\XGISAustralia\Applications\xPaypal\Controls\xt_PaymentSelector.ascx.cs    Line: 129

Stack Trace:


[InvalidOperationException: Token EndDocument in state Document would result in an invalid XML document.]
   System.Xml.XmlWellFormedWriter.ThrowInvalidStateTransition(Token token, State currentState) +246
   System.Xml.XmlWellFormedWriter.AdvanceState(Token token) +4051377
   System.Xml.XmlWellFormedWriter.WriteEndDocument() +160
   System.Xml.Linq.XDocument.WriteTo(XmlWriter writer) +134
   System.Xml.Linq.XDocument.Save(String fileName, SaveOptions options) +151
   System.Xml.Linq.XDocument.Save(String fileName) +25
   Applications_xTrain_Controls_xt_PaymentSelector.Button1_Click(Object sender, EventArgs e) in e:\Projects\Development\XGISAustralia\Applications\xPaypal\Controls\xt_PaymentSelector.ascx.cs:129
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

 


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

Please find attached the code used to get this error

    protected void Button1_Click(object sender, EventArgs e)
    {
        foreach (GridDataItem item in RadGrid1.MasterTableView.Items)
        {
            CheckBox chk = (CheckBox)item.FindControl("CheckBox1");
            if (chk.Checked)
            {
                if (!File.Exists(Server.MapPath("~/App_Data/XML") + "\\Orders.xml"))
                {

                    XmlTextWriter textWritter = new XmlTextWriter(Server.MapPath("~/App_Data/XML") + "\\cart.xml", null);
                    textWritter.WriteStartDocument();
                    textWritter.WriteStartElement("Orders");
                    textWritter.WriteEndElement();

                    textWritter.Close();
                }

                XDocument Orders = new XDocument();
                string xml = @"<OrderItems ProductID=""{0}"" ProductName=""{1}"" ProductDesc=""{2}"" ProductPrice=""{3}""/>";
//                string xml = @"<OrderItems ProductID=""{0}"" OrderID=""{1}"" ProductName=""{2}"" ProductDesc=""{3}"" Qty=""{4}"" Currency=""{5}"" ProductPrice=""{6}""/>";

                var dataTable = new DataTable("Cart_Items");

                dataTable.Columns.Add("Product_ID");
                dataTable.Columns.Add("ProductName");
                dataTable.Columns.Add("ProductDesc");
                //dataTable.Columns.Add("Qty");
               // dataTable.Columns.Add("Currency");
                dataTable.Columns.Add("ProductPrice");


                foreach (GridDataItem gridDataItem in RadGrid1.SelectedItems)
                {
                    var hashtable = new Hashtable();
                    gridDataItem.ExtractValues(hashtable);

                    DataRow dataRow = dataTable.NewRow();
                    foreach (DictionaryEntry entry in hashtable)
                    {
                        dataRow[entry.Key.ToString()] = entry.Value;
                    }
                    dataTable.Rows.Add(dataRow);
                    //Code to generate XML
                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["ProductPrice"].ToString()));
//                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["Qty"].ToString(), hashtable["Currency"].ToString(), hashtable["ProductPrice"].ToString()));
                    Orders.Add(prod);
                }
                Orders.Save(Server.MapPath("~/App_Data/XML") + "\\Orders.xml");
            }
        }
    }

Open in new window


0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 34171788
Your Orders object is not well made
when you say
XDocument Orders = new XDocument();
It does not create a node so your XML does not have a root node at all and thats why this error
instead of
XDocument Orders = new XDocument();
write the line
XElement Orders = new XElement("Orders");
rest should remain same
0
 
LVL 7

Author Comment

by:XGIS
ID: 34171889
sorry to bother you again::

since the database is still being developed i commented and removed a couple of feilds, this is the current error;
Server Error in '/XGISAustralia' Application.
--------------------------------------------------------------------------------

Object reference not set to an instance of an object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error:


Line 124:                    dataTable.Rows.Add(dataRow);
Line 125:                    //Code to generate XML
Line 126:                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["ProductPrice"].ToString()));
Line 127://                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["Qty"].ToString(), hashtable["Currency"].ToString(), hashtable["ProductPrice"].ToString()));
Line 128:                    Orders.Add(prod);
 

Source File: e:\Projects\Development\XGISAustralia\Applications\xPaypal\Controls\xt_PaymentSelector.ascx.cs    Line: 126

Stack Trace:


[NullReferenceException: Object reference not set to an instance of an object.]
   Applications_xTrain_Controls_xt_PaymentSelector.Button1_Click(Object sender, EventArgs e) in e:\Projects\Development\XGISAustralia\Applications\xPaypal\Controls\xt_PaymentSelector.ascx.cs:126
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563

 


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1

and here is the code::

C#
    protected void Button1_Click(object sender, EventArgs e)
    {
        foreach (GridDataItem item in RadGrid1.MasterTableView.Items)
        {
            CheckBox chk = (CheckBox)item.FindControl("CheckBox1");
            if (chk.Checked)
            {
                if (!File.Exists(Server.MapPath("~/App_Data/XML") + "\\Orders.xml"))
                {

                    XmlTextWriter textWritter = new XmlTextWriter(Server.MapPath("~/App_Data/XML") + "\\cart.xml", null);
                    textWritter.WriteStartDocument();
                    textWritter.WriteStartElement("Orders");
                    textWritter.WriteEndElement();

                    textWritter.Close();
                }

                //XDocument Orders = new XDocument();
                XElement Orders = new XElement("Orders");
                string xml = @"<OrderItems ProductID=""{0}"" ProductName=""{1}"" ProductDesc=""{2}"" ProductPrice=""{3}""/>";
//                string xml = @"<OrderItems ProductID=""{0}"" OrderID=""{1}"" ProductName=""{2}"" ProductDesc=""{3}"" Qty=""{4}"" Currency=""{5}"" ProductPrice=""{6}""/>";

                var dataTable = new DataTable("Cart_Items");

                dataTable.Columns.Add("Product_ID");
                dataTable.Columns.Add("ProductName");
                dataTable.Columns.Add("ProductDesc");
                //dataTable.Columns.Add("Qty");
               // dataTable.Columns.Add("Currency");
                dataTable.Columns.Add("ProductPrice");


                foreach (GridDataItem gridDataItem in RadGrid1.SelectedItems)
                {
                    var hashtable = new Hashtable();
                    gridDataItem.ExtractValues(hashtable);

                    DataRow dataRow = dataTable.NewRow();
                    foreach (DictionaryEntry entry in hashtable)
                    {
                        dataRow[entry.Key.ToString()] = entry.Value;
                    }
                    dataTable.Rows.Add(dataRow);
                    //Code to generate XML
                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["ProductPrice"].ToString()));
//                    XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["Qty"].ToString(), hashtable["Currency"].ToString(), hashtable["ProductPrice"].ToString()));
                    Orders.Add(prod);
                }
                Orders.Save(Server.MapPath("~/App_Data/XML") + "\\Orders.xml");
            }
        }
    }

Open in new window


XHTML
<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server" LoadingPanelID="RadAjaxLoadingPanel1"
    SkinID="Black" Width="645px">
    <telerik:RadGrid ID="RadGrid1" runat="server" Skin="Black" Width="640px" GridLines="None"
        DataSourceID="SqlDataSource2" AutoGenerateColumns="False" EnableLinqExpressions="False"
        BackColor="Transparent" AllowMultiRowSelection="True" OnItemCommand="RadGrid1_ItemCommand">
        <MasterTableView Summary="Video Lessons" ShowGroupFooter="false" AllowMultiColumnSorting="true"
            DataSourceID="SqlDataSource2" DataKeyNames="Product_ID">
            <CommandItemSettings ExportToPdfText="Export to Pdf" />
            <Columns>
                <telerik:GridTemplateColumn>
                    <ItemTemplate>
                        <asp:CheckBox ID="CheckBox1" runat="server" />
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn HeaderText="" SortExpression="XTV7_Categories_Image"
                    UniqueName=" XTV7_Categories_Image">
                    <ItemTemplate>
                        <asp:ImageButton ID="btnImageDisplay" runat="server" CommandName="Select" ImageUrl='<%# "~/App_Portal/xTrain/Images/CategoryLogos/" + Eval(" XTV7_Categories_Image") %>'
                            Width="100px" />
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridBoundColumn DataField="ProductName" HeaderText="Product Name"
                    SortExpression="ProductName" UniqueName="ProductName" Visible="true">
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn DataField="ProductDesc" HeaderText="Overview" SortExpression="ProductDesc"
                    UniqueName="ProductDesc" Visible="true">
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn DataField="VidCount" HeaderText="VidCount" SortExpression="VidCount"
                    UniqueName="VidCount" Visible="true" ReadOnly="true">
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn DataField="ProductPrice" HeaderText="Cost" SortExpression="ProductPrice"
                    UniqueName="ProductPrice" Visible="true">
                </telerik:GridBoundColumn>
                <telerik:GridBoundColumn DataField="Product_ID" DataType="System.Int32" HeaderText="Product #"
                    SortExpression="Product_ID" UniqueName="Product_ID" Visible="false">
                </telerik:GridBoundColumn>
            </Columns>
        </MasterTableView>
        <ClientSettings>
            <Selecting AllowRowSelect="True" />
        </ClientSettings>
    </telerik:RadGrid>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="ClientClick();"
        OnClick="Button1_Click" />
</telerik:RadAjaxPanel>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:XtrainConnectionString %>"
    
    SelectCommand="SELECT TOP (100) PERCENT XTV7_Categories_ID AS Product_ID, XTV7_Categories_Name AS ProductName, Overview AS ProductDesc, Videos AS VidCount, Cost AS ProductPrice, XTV7_Categories_Image FROM vw_xt_ddl_categories">
</asp:SqlDataSource>

Open in new window


0
 
LVL 7

Author Comment

by:XGIS
ID: 34171893
the error is on line 126
0
 
LVL 7

Author Comment

by:XGIS
ID: 34172475
I mean XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["ProductPrice"].ToString()));
0
 
LVL 7

Author Comment

by:XGIS
ID: 34179455
?????
0
 
LVL 19

Expert Comment

by:arif_eqbal
ID: 34185431
well the Error says some object is NULL
If I look at the line
XElement prod = XElement.Parse(string.Format(xml, hashtable["Product_ID"].ToString(), "", hashtable["ProductName"].ToString(), hashtable["ProductDesc"].ToString(), hashtable["ProductPrice"].ToString()));

there's only 2 object used one is the string "xml" the other is the object "hashtable" now looking at the code neither of them appear to be null. So the error might not really be on this line but somewhere else. You can put a breakpoint and check, run the code in debug and on the line where it breaks hover your mouse to check which obejct is null.
 
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question