Reputation: 21
I am trying to add (insert) a new <Period></Period>
element into the following XML;
<?xml version="1.0" encoding="utf-8"?>
<Scheduler>
<Module guid="64A3EB4C-7F34-47F3-8894-933CB0048D87">
<RetrieveDays>1</RetrieveDays>
<Schedule>
<Period>1</Period>
<Period>33</Period>
<Period>49</Period>
<Period>73</Period>
</Schedule>
</Module>
</Scheduler>
So for example, I pass the value 96, the new XML would look like;
<?xml version="1.0" encoding="utf-8"?>
<Scheduler>
<Module guid="64A3EB4C-7F34-47F3-8894-933CB0048D87">
<RetrieveDays>1</RetrieveDays>
<Schedule>
<Period>1</Period>
<Period>33</Period>
<Period>49</Period>
<Period>73</Period>
<Period>96</Period>
</Schedule>
</Module>
</Scheduler>
Using the following code;
// period is the new value
XDocument xmlDoc = new XDocument();
xmlDoc = XDocument.Load(String.Format(@"{0}\{1}", settingsDir, settingsFilename));
XElement periodNodes = xmlDoc.Root.Descendants("Module").Where(i => (String)i.Attribute("guid") == moduleGuId).First().Element("Schedule");
if (periodNodes.Descendants("Period").Where(x => x.Value == period.ToString()).Count() == 0)
periodNodes.Add(new XElement("Period", period.ToString()));
xmlDoc.Save(String.Format(@"{0}\{1}", settingsDir, settingsFilename));
But unfortunately no new <Period></Period>
element gets created. I have checked that the XML is valid, which it is. I tried renaming the element, but to no change.
I cannot find a solution, what am I missing?
Well, this is embarrassing: I restarted the computer and VS and now it works - go figure. Nonetheless, thank you all for such quick responses and suggestions.
Upvotes: 0
Views: 1116
Reputation: 11773
In VB using XElement it would look like this,
Dim xe As XElement
'to load from a file
' xe = XElement.Load("Your Path Here")
' for testing
xe = <Scheduler>
<Module guid="64A3EB4C-7F34-47F3-8894-933CB0048D87">
<RetrieveDays>1</RetrieveDays>
<Schedule>
<Period>1</Period>
<Period>33</Period>
<Period>49</Period>
<Period>73</Period>
</Schedule>
</Module>
</Scheduler>
Dim moduleGuId As String = "64A3EB4C-7F34-47F3-8894-933CB0048D87"
Dim theVal As Integer = 96
Dim ie As IEnumerable(Of XElement)
ie = From el In xe.<Module> Where el.@guid = moduleGuId Take 1
From sel In el.<Schedule>...<Period> Where sel.Value = theVal.ToString Select sel
If ie.Count = 0 Then
xe...<Schedule>.LastOrDefault.Add(<Period><%= theVal %></Period>)
End If
' xe.Save("path here")
Upvotes: 0
Reputation: 3231
Know that you've figured out the issue but you can eliminate a lot of your code by using XPath.
var schedulerSelect = string.Format("//Module[@guid='{0}']/Schedule",guid);
var periodSelect = string.Format("Period[text()={0}]",period);
var node = doc.XPathSelectElement(schedulerSelect+"/"+periodSelect);
if(node == null)
{
node = doc.XPathSelectElement(schedulerSelect);
if(node!=null)
node.Add(new XElement("Period",period));
}
You can see a working version I created on .NET Fiddle here
Upvotes: 1
Reputation: 7352
Use this code
XDocument doc = XDocument.Load(String.Format(@"{0}\{1}", settingsDir, settingsFilename));
var query = doc.Descendants("Schedule");
var q2 = query.Descendants("Period").Where(a => a.Value == period.ToString()).Select(b => b);
if (q2.Count() == 0)
{
query.FirstOrDefault().Add(new XElement("Period", period.ToString()));
doc.Save(String.Format(@"{0}\{1}", settingsDir, settingsFilename));
}
Upvotes: 0
Reputation: 2199
Be sure not to have the file open in another application and that the account the application is running under has rights to write to that file. Try creating a new file instead, this will eliminate the file write access; unless the user account doesn't have write permissions on that directory.
For testing purposes try changing the final line to this...
xmlDoc.Save(String.Format(@"{0}\{1}2", settingsDir, settingsFilename));
Upvotes: 1