Reputation: 89
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
Upvotes: 0
Views: 113
Reputation: 14251
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))
Upvotes: 2
Reputation: 21
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);
}
Upvotes: 1
Reputation: 23837
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; }
}
Upvotes: 1