Reputation: 149
I am making a “simple” program to update an xml file.
XML snippet
<statistics>
<offices location=”city1” >
<office name=”office1”/>
<office name=”office2”/>
</offices>
<offices location=”city2” >
<office name=”office3”/>
<office name=”office4”/>
</offices>
</statistics>
My sequence of events is:
Load the xml into a treeview
Delete some children, add some, move some between parents in the treeview.
Delete all the children in the xml.
Traverse the treeview and add the children back in the xml.
Save the file.
The problem is that when I delete all the children the </offices>
tag is removed in order to preserve integrity and I am left with
<offices location=”city1” />
<offices location=”city2” />
If I now insert the new offices I get
<offices location=”city1” />
<office name=”office1”/>
<office name=”office2”/>
<offices location=”city2” />
<office name=”office3”/>
<office name=”office4”/>
Is there a way to delete the children and keep the </offices>
tag or am I going about this all wrong?
Thanks for any help,
Gerry.
This is how I delete the children
private void deleteAllOffices(XDocument doc)
{
var offices = doc.Root.Descendants("offices").ToList();
foreach (var factor in offices)
{
var location = factor.Attribute("location").Value;
// Delete the children
deleteChildren(doc, location);
}
}
private void deleteChildren(XDocument doc, string catg)
{
var lv1s = from lv1 in doc.Descendants("offices")
where lv1.Attribute("location").Value.Equals(catg)
select new
{
Children = lv1.Descendants("office")
};
//Loop through results
foreach (var lv1 in lv1s)
{
foreach (var lv2 in lv1.Children.ToArray())
lv2.Remove();
}
}
This is how I add the offices back to the xml
// First delete all the offices
deleteAllOffices(doc);
// Now add the offices from the treeview
//Create a TreeNode to hold the Parent Node
TreeNode temp = new TreeNode();
//Loop through the Parent Nodes
for (int k = 0; k < treeView1.Nodes.Count; k++)
{
//Store the Parent Node in temp
temp = treeView1.Nodes[k];
//Now Loop through each of the child nodes in this parent node i.e.temp
for (int i = 0; i < temp.Nodes.Count; i++)
{
doc.Element("statistics")
.Elements("offices")
.Where(item => item.Attribute("location").Value == temp.Text).FirstOrDefault()
.AddAfterSelf(new XElement("office", new XAttribute("name", temp.Nodes[i].Text)));
}
}
doc.Save(@"d:\temp\stats.xml");
Upvotes: 0
Views: 131
Reputation: 39339
The problem is in that AddAfterSelf method: that adds the new XElement after the current node, as sibling where you need child.
You need the Add method of XElement (or rather XContainer) to add that new XElement as a child element.
By the way, for XML <offices location="city1" />
is identical to <offices location="city1"></offices>
Upvotes: 1