2016-08-02 140 views
0

我试图在下面的XML中添加(插入)新的<Period></Period>元素;C# - 使用LINQ XML向XML文件添加新元素(XDocument/XElement)

<?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> 

因此,例如,我传递值96,新的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> 
     <Period>96</Period> 
    </Schedule> 
    </Module> 
</Scheduler> 

使用下面的代码;

// 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)); 

但遗憾的是没有新的<Period></Period>元素被创建。我检查了XML是有效的,它是。我尝试重命名元素,但没有改变。

我一直在挠我的头几个小时,找不到解决方案,我错过了什么?任何帮助,将不胜感激!

**** ****更新

那么,这是尴尬的:我重新启动电脑,VS和现在的作品...进入数字。尽管如此,谢谢大家如此快速的回应和建议。

+0

有你通过它加强并检查'periodNodes.Add'实际上是叫? –

+0

在问我们之前,您可以[使用调试器](http://www.codeproject.com/Articles/79508/Mastering-Debugging-in-Visual-Studio-A-Beginn)遍历代码并检查你的'if'语句中的子句实际上评估为真,如果不是,为什么不 –

+0

检查[这个小提琴](https://dotnetfiddle.net/Wfh7iq) - 你的代码工作正常。如果您仍然遇到问题,请添加[mcve]。 –

回答

0

使用此代码

 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)); 
     } 
+0

这删除了一堆的时间和地点添加周期的逻辑。而且,由于问题中的代码[实际上工作正常](https://dotnetfiddle.net/Wfh7iq),目前尚不清楚这将如何解决问题。 –

+0

@Mostafiz:谢谢你的建议。 – user1224125

+0

@ user1224125看到我最新的更新希望这是你想要的 – Mostafiz

1

切勿在其他应用程序和应用程序在其下运行的帐户有权写入该文件打开该文件。尝试创建一个新文件,这将消除文件写访问;除非用户帐户对该目录没有写权限。

出于测试目的,尝试改变最后一行到这个...

xmlDoc.Save(String.Format(@"{0}\{1}2", settingsDir, settingsFilename)); 
0

知道你已经想通了这个问题,但你可以通过使用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)); 
} 

你可以看到我使用的XElement它看起来像这样的.NET Fiddle here

0

建立在VB中工作版本,

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 [email protected] = 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")