заменить элемент XML - PullRequest
       2

заменить элемент XML

4 голосов
/ 08 июня 2010

Я делаю что-то подобное:

var results = from d in myDocument.Elements().Descendants("myName") select d;

foreach (var result in results){
   if (sth...){
      result.replace(myXElement);
   }
}

Проблема в том, что когда я заменяю элемент, я не могу перейти к следующему элементу, потому что есть нулевая ссылка (различные результаты в результате).

Есть ли другой способ заменить этот элемент другим, и при этом иметь возможность перебирать этот документ?

спасибо за помощь

трассировка стека:

System.NullReferenceException was unhandled
  Message="Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu."

Source="System.Xml.Linq"
  StackTrace:
       w System.Xml.Linq.XContainer.d__a.MoveNext()
       w System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
       w DocSorter.Merge.MergeFiles(String contentFilePath, String directoryPath) w D:\DocSorter\DocSorter\Merge.cs:wiersz 39
       w DocSorter.MainBox.btnMergeFiles_Click(Object sender, EventArgs e) w D:\DocSorter\DocSorter\MainBox.cs:wiersz 85
       w System.Windows.Forms.Control.OnClick(EventArgs e)
       w System.Windows.Forms.Button.OnClick(EventArgs e)
       w System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       w System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       w System.Windows.Forms.Control.WndProc(Message& m)
       w System.Windows.Forms.ButtonBase.WndProc(Message& m)
       w System.Windows.Forms.Button.WndProc(Message& m)
       w System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       w System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       w System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       w System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       w System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       w System.Windows.Forms.Application.Run(Form mainForm)
       w DocSorter.Program.Main() w D:\DocSorter\DocSorter\Program.cs:wiersz 18
       w System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       w System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       w Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       w System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       w System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       w System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Ответы [ 2 ]

3 голосов
/ 08 июня 2010

Вы не можете изменять IEnumerable во время его циклического перемещения.

Поскольку LINQ to XML использует отложенное выполнение, он пытается найти потомков при изменении XML.

Чтобы исправить это, вам нужно поместить элементы в массив перед их циклическим просмотром, например:

var results = myDocument.Descendants("myName").ToArray();

foreach (var result in results){
   if (sth...){
      result.replace(myXElement);
   }
}

Вызывая ToArray(), вы заставляете его перечислять элементы сразу, а не находить их, пока вы их просматриваете.

0 голосов
/ 14 мая 2014

Похоже, вы применили свой собственный метод расширения replace(myXElement). Но похоже, что XNode.ReplaceWith Method (Object) удовлетворит вашу потребность в этой ситуации.

Вот пример Microsoft для ReplaceWith(Object), взятый из ее документации:

== Код ==

XElement xmlTree = new XElement("Root",
    new XElement("Child1", "child1 content"),
    new XElement("Child2", "child2 content"),
    new XElement("Child3", "child3 content"),
    new XElement("Child4", "child4 content"),
    new XElement("Child5", "child5 content")
);

XElement child3 = xmlTree.Element("Child3");

child3.ReplaceWith(
    new XElement("NewChild", "new content")
);

Console.WriteLine(xmlTree);

== Ожидаемый результат ==

<Root>
  <Child1>child1 content</Child1>
  <Child2>child2 content</Child2>
  <NewChild>new content</NewChild>
  <Child4>child4 content</Child4>
  <Child5>child5 content</Child5>
</Root>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...