2016-08-02 138 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")