View Full Version : Read Spefcific XML Nodes into a DataGrid
hodgesp
09-06-2007, 02:11 PM
I create an XML File and I get to a section where I create some child nodes within the section. I need to immediatly tie those child nodes to a DataGrid, and be able to edit them, or at least tie them to the datagrid so they are displayed as I add additonal tags.
This is the Structure:
<Section2>
<text>Section 2 Description Text goes here</text>
<cost1 value="10.11">test text cost 1 section 2</cost1>
<cost2 value="20.22">test text cost 2 section 2</cost2>
etc.........
</Section2>
The Cost Tag value attributes and the text between them is what I need to add to the datagrid. One element to a column. Being new to XML it is a pretty hard task for me. Any help will be greatly appreciated.
PremiumBlend
09-06-2007, 03:04 PM
I assume by DataGrid, you're using .Net, is that right? Also, what is producing the XML file?
In the XML where you have:
<cost1 value="10.11">test text cost 1 section 2</cost1>
<cost2 value="20.22">test text cost 2 section 2</cost2>
It should look something more like:
<cost id="1" value="10.11">test text cost 1 section 2</cost>
<cost id="2" value="20.22">test text cost 2 section 2</cost>
See how you then have multiple <cost> element types instead of many different element names. This is much easier then, you can use (if it is .Net)...
xmlFile.SelectNodes("//cost")
to get all the cost elements and parse from there.
hodgesp
09-06-2007, 04:01 PM
Yes I'm using c#. I appoligize for not stating that.
I'm trying to create a Cost Estimating web app, in .net, that will generate a flat file that I will eventually want to export to a crystal report/pdf.
Each page is a different section but the coding sghould be very similar. I am new to XML but I was able to create the file no problem.
Some of the pages just need to generate tag like so:
<section 1>
<text>This is some Text</text>
</section 1>
I got that down. But I need help on sections that will require an unknown number of cost child nodes in the format I noted. I can very easily change my cost tags to be <cost> instead of <cost 1 2 3...> if that would be better. Thank You for that one.
After I create the <cost> nodes how can I display them in the datagrid?
I have a datagrid that I placed on the page and I use the footer section to add the child nodes. It works as far as adding the child nodes to the xml file, but I would like it of after I add a cost node(s) that they are displayed in the item section of the datagrid.
Here is the code i use to generate the cost nodes. I placed this code in the DataGrid1_ItemCommand event.
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNode s2 = doc.SelectSingleNode("/Root/Section2");
XmlElement cost = null;
XmlAttribute valattrib = null;
// Create New cost XML Element
cost = doc.CreateElement("cost");
// New Attribute
valattrib = doc.CreateAttribute("value");
// Value given for the new attribute
// ---valattrib.Value = "99.99";
TextBox tbCostAdd = new TextBox();
tbCostAdd = (TextBox)e.Item.FindControl("tbCostAdd");
valattrib.Value = tbCostAdd.Text;
// Attach the attribute to the XML element
cost.SetAttributeNode(valattrib);
// Value given for the cost element
TextBox tbDescrAdd = new TextBox();
tbDescrAdd = (TextBox)e.Item.FindControl("tbDescrAdd");
cost.InnerText = tbDescrAdd.Text;
s2.AppendChild(cost);
doc.Save(fileName);
bindGrid();
And my bindgrid function:
private void bindGrid()
{
if (Cache["Section2"] == null)
{
//if There is no Section2 item in the Cache...
DataSet ds = new DataSet();
ds.ReadXml(fileName); //--read the xml file--//
//create dependancy
CacheDependency dep = new CacheDependency(fileName);
//Add it to the Cache
Cache.Insert("Section2",ds,dep);
}
//Set the DataGrid's DataSource to the cached DataSet
DataGrid1.DataSource = Cache["Section2"];
DataGrid1.DataBind();
}
Basically, I'm taking it step by step, learning as I go. So my current question is:
How do I display the <cost> child nodes (the value attribute in the first column, the innerText of the tag in the text box in the second column) in consecutive rows?
Your help is Greatly appreciated!!
PremiumBlend
09-06-2007, 08:24 PM
Can you give an example of the all the data you want to include in the datagrid? If I see the whole thing I might be able to propose an XML file template that would be really easy to bind to a datagrid.
hodgesp
09-06-2007, 08:53 PM
Basically it will be the same for all sections but each section is seperate.
<?xml version="1.0" ?>
- <Root>
<UserName>Kizer Sozay</UserName>
<FileTitle>xmlTest</FileTitle>
<FileDate>01/01/2007</FileDate>
- <Section1>
<text>this is section 1 text</text>
</Section1>
- <Section2>
<text>this is section 2 text</text>
<cost value="100.99">first cost for section 2</cost>
<cost value="22.99">second cost for section 2</cost>
<cost value="33.33">3rd cost for sectuion 2</cost>
etc...
</Section2>
</Root>
Note that all following section 3, 4, 5, etc will be exactly like section 2.
By the way I was able to load the innerText into the datagrid. It displays in the second column. How can I load the value attribute value (that sounds wierd!) into the Cost column of the datagrid? Here is my simplified bindGrid function:
private void bindGrid()
{
XmlDocument xmlFile = new XmlDocument();
xmlFile.Load(fileName);
DataGrid1.DataSource = xmlFile.GetElementsByTagName("cost");
DataGrid1.DataBind();
}
the Cost Description (InnerText,InnerXML,OuterText) Displays Fine in the CostDescr Column <<==(The Red Tags)
Note the Purple Template Tags. I'm attempting to pass the attribute value to the datagrid, but no luck so far. I'm not sure how to designate them so the .net can access the value attribute. It passes to the XML file OK, just doesn't display in the datagrid.
<asp:datagrid id="DataGrid1" runat="server" Width="882px" AutoGenerateColumns="False" ShowFooter="True">
<Columns>
<asp:TemplateColumn HeaderText="Cost">
<ItemTemplate>
<asp:Label id=lblCost runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.value") %>'>
</asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id=tbCostAdd runat="server" Width="100%" Text='<%# DataBinder.Eval(Container, "DataItem.value") %>'>
</asp:TextBox>
</FooterTemplate>
<EditItemTemplate>
<asp:TextBox id=tbCostEdit runat="server" Width="100%" Text='<%# DataBinder.Eval(Container, "DataItem.value") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Description">
<HeaderStyle Width="80%"></HeaderStyle>
<ItemTemplate>
<asp:Label id=lblCostDescr runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.innerText") %>'>
</asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox id=tbCostDescrAdd runat="server" Width="100%" TextMode="MultiLine" Text='<%# DataBinder.Eval(Container, "DataItem.innerText") %>'>
</asp:TextBox>
</FooterTemplate>
<EditItemTemplate>
<asp:TextBox id=tbCostDescrEdit runat="server" Width="100%" TextMode="MultiLine" Text='<%# DataBinder.Eval(Container, "DataItem.innerText") %>'>
</asp:TextBox>
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:datagrid>
Anyway I seem to be making some small progress But I have a long way to go. I hope I have given enough info for you to suggest a path forward.
Thank You Very Many :thumbsup:
PremiumBlend
09-06-2007, 09:31 PM
I'm not able to test this code, but play around and you can try this as the event handler for the DataGrid.
private void DataGrid_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
Xml.XmlNode node = (XmlNode)e.Item.DataItem;
// now you have 'node' as a varible for each XmlNode that is bound to the grid.
Xml.XmlAttribute val = node.Attributes.Item["value"];
// now you have the attribute 'value'
}
Also, don't forget to set this event handler to the data grid similarly to this in InitializeComponent():
this.DataGrid.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid_ItemDataBound);
hodgesp
09-06-2007, 09:58 PM
I couldn't get the attribute part to work however, I already have the attribute value note the code. I was able to display the value with a response.write. I just can't seem to get it into the datagrid.:confused:
:D
private void DataGrid1_ItemCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNode s2 = doc.SelectSingleNode("/Root/Section2");
XmlElement cost = null;
XmlAttribute valattrib = null;
//Create New cost XML Element
cost = doc.CreateElement("cost");
//New Attribute
valattrib = doc.CreateAttribute("value");
//Value given for the new attribute
TextBox tbCostAdd = new TextBox();
tbCostAdd = (TextBox)e.Item.FindControl("tbCostAdd");
Response.Write(tbCostAdd.Text +"<br/>");
valattrib.Value = tbCostAdd.Text;
//Attach the attribute to the XML element
cost.SetAttribute(valattrib.Name,tbCostAdd.Text);
// Value given for the cost element
TextBox tbCostDescrAdd = new TextBox();
tbCostDescrAdd = (TextBox)e.Item.FindControl("tbCostDescrAdd");
cost.InnerText = tbCostDescrAdd.Text;
s2.AppendChild(cost);
doc.Save(fileName);
bindGrid();
}
PremiumBlend
09-06-2007, 10:29 PM
Ok, I had some time to test real quick. The code I posted that didn't work for you was for various (dumb in hindsight) reasons. Give this a try:
private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
switch(e.Item.ItemType)
{
case ListItemType.AlternatingItem:
((TableRow)e.Item).Cells[0].Text = ((XmlElement)e.Item.DataItem).Attributes["value"].InnerText;
break;
case ListItemType.Item:
((TableRow)e.Item).Cells[0].Text = ((XmlElement)e.Item.DataItem).Attributes["value"].InnerText;
break;
default:
break;
}
}
hodgesp
09-06-2007, 11:09 PM
:thumbsup:
Wooo-Whoooo
It Worked Bubba Dog! Now I will add the same script to the other section pages.
Thats one obsticle overcome.
Next I will tackle export to Crystal Reports then Uploading and Editing an exsiting XML file.
If you have any suggestions trot them out.
Thank You Very Many for the help!! :D
PremiumBlend
09-07-2007, 03:29 PM
No problem. That was actually a good exercise for me, and gave me a good idea for a client's website that I'm working on!
vBulletin® v3.8.2, Copyright ©2000-2010, Jelsoft Enterprises Ltd.