2016-08-02 6 views
0

Я пытаюсь добавить (добавить) новый элемент <Period></Period> в следующий XML;C# - Добавление нового элемента в файл XML с использованием LINQ 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' фактически вычисляется значение true, а если нет, то почему не –

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

Вы можете увидеть рабочую версию я создал на .NET Fiddle here

0

В VB с помощью XElement это будет выглядеть так,

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") 

 Смежные вопросы

  • Нет связанных вопросов^_^