Populate Datagrid From xml file


Populate Datagrid From xml file



I've looked at many answers on this topic but was unable to find the answer to my question, so apologies in advance if I missed this answer somewhere else.



I would like to add attributes of a particular object id to a datagrid. The routine that I have developed unfortunately adds all attributes to the datagrid and not just the attributes of the selected object.



I have the following xml file structure:


<?xml version="1.0" encoding="UTF-8"?>
<project>
<configuration>
<general>
<verbose>True</verbose>
</general>
<architecture>
<site reference="Demo Site Reference" type="WTP" id="0001" />
<rtu dnp="77" ip="10.10.10.77" type="Schneider Electric SCADAPack 442" />
<radio ip="10.10.10.76" />
<hmi ip="10.10.10.75" />
</architecture>
</configuration>
<database>
<object id="0" name="object 0" description="Entry Description 0" date="22.06.2018 00:00:00" archestra="Export">
<attributes>
<attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
<attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
</attributes>
</object>
<object id="1" name="object 1" description="Entry Description 1" date="22.06.2018 00:00:00" archestra="Export">
<attributes>
<attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
<attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
<attribute id="2" name="Attribute 2" description="Attribute 2 Description" note="Attribute 2 Note" />
<attribute id="3" name="Attribute 3" description="Attribute 3 Description" note="Attribute 3 Note" />
</attributes>
</object>
<object id="2" name="object 2" description="Entry Description 2" date="22.06.2018 00:00:00" archestra="Export">
<attributes>
<attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
<attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
<attribute id="2" name="Attribute 2" description="Attribute 2 Description" note="Attribute 2 Note" />
</attributes>
</object>
</database>
</project>



The following routine adds all attributes:


public static DataTable PopulateGrid(string file, string id)
{
//DataTable that will hold the found results
DataTable results = new DataTable("SearchResults");
//DataRow (used later)
DataRow row = null;

results.Columns.Add("id", typeof(string));
results.Columns.Add("name", typeof(string));
results.Columns.Add("description", typeof(string));

XmlDocument xmldocument = new XmlDocument();
xmldocument.Load(file);

//** Change This **
string query = "/project/database/object";
string query2 = "/project/database/object/attributes/attribute";

//now we loop through the list
foreach (XmlNode xmlnode in xmldocument.SelectNodes(query))
{
if (xmlnode.Attributes["id"].Value == id)
{
foreach (XmlNode xmlnode2 in xmldocument.SelectNodes(query2))
{
row = results.NewRow();

row[0] = xmlnode2.Attributes["id"].Value;
row[1] = xmlnode2.Attributes["name"].Value;
row[2] = xmlnode2.Attributes["description"].Value;

results.Rows.Add(row);
}
}
}

//now return the DataTable
return results;
}



Any help to solve this would be greatly appreciated.



Kind Regards




3 Answers
3



You have to get the attributes from the already found node, not from the entire document.


string query2 = "./attributes/attribute"; // path from current node


// use xmlnode instead of xmldocument
foreach (XmlNode xmlnode2 in xmlnode.SelectNodes(query2))



I think it would be much easier if you have used Linq To XML. ie:


public static IEnumerable<MyData> PopulateGrid(string file, string id)
{
var xml = XElement.Load(file);
var result = xml.Element("database").Elements("object")
.SelectMany(o => o.Element("attributes").Elements("attribute"))
.Where(x => (string)x.Attribute("id") == id)
.Select(a => new MyData
{
Id = (string)a.Attribute("id"),
Name = (string)a.Attribute("name"),
Description = (string)a.Attribute("description")
});

return result;
}

public class MyData
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}



In your second for loop, you call


xmldocument.SelectNodes(query2)



which selects all the nodes from the document which match query2.



your could change your code to:


string query = "/project/database/object['" + id + "']";
string query2 = "attributes/attribute";

var obj = xmldocument.SelectSingleNode(query);

foreach (XmlNode xmlnode2 in obj.SelectNodes(query2))
{
row = results.NewRow();

row[0] = xmlnode2.Attributes["id"].Value;
row[1] = xmlnode2.Attributes["name"].Value;
row[2] = xmlnode2.Attributes["description"].Value;

results.Rows.Add(row);
}





as far as I can deduce that your above suggestion would simply remove the need for the if-statement, and would still list all attributes from all objects. Or am I missing something?
– Juan Le Roux
Jul 2 at 9:48





Yes thats true, I didn't test my solution. I will update my answer.
– croth
Jul 2 at 9:57






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Rothschild family

Cinema of Italy