Попытка использовать RemoveChild() для XmlNodeList портит мою коллекцию XmlNode

Я пытаюсь удалить определенный узел из списка XmlNodeList с именем listaWidths. В этом конкретном списке есть 5 элементов, прежде чем я использую RemoveChild(). Но после оператора RemoveChild() список остается только с 1 элементом.

XmlNodeList listaWidths = xmlDoc.SelectNodes("/MsBuild:Report/MsBuild:Body/MsBuild:ReportItems/MsBuild:Tablix/MsBuild:TablixBody/MsBuild:TablixColumns/*", nsmgr);                
int indexEpoca = 0;
XmlNode node = listaWidths[indexEpoca];
XmlNode parent = listaWidths[indexEpoca].ParentNode;
parent.RemoveChild(node);

Это XML-файл RDL Reporting Services. Конкретный код XML находится здесь:

  <Tablix Name="Tablix3">
    <TablixBody>
      <TablixColumns>
        <TablixColumn>
          <Width>1.602in</Width>
        </TablixColumn>
        <TablixColumn>
          <Width>1.61in</Width>
        </TablixColumn>
        <TablixColumn>
          <Width>1.6323in</Width>
        </TablixColumn>
        <TablixColumn>
          <Width>1.6023in</Width>
        </TablixColumn>
        <TablixColumn>
          <Width>1.6033in</Width>
        </TablixColumn>
      </TablixColumns>
      (...)

Я перепробовал все возможные комбинации, но безрезультатно. Что я делаю не так? Спасибо.


person nevizi    schedule 22.03.2010    source источник
comment
Извините, в чем конкретно проблема? В каком списке, как вы говорите, после этого будет ноль, и как вы это определяете?   -  person John Saunders    schedule 23.03.2010
comment
После метода removeChild() в списке listaWidths есть только 1 элемент, тогда как в нем должно быть 4, как изначально было 5. Я наблюдаю за переменной, и как только метод removeChild() выполняется, в списке есть только один предмет.   -  person nevizi    schedule 23.03.2010


Ответы (1)


В документации SelectNodes четко сказано: "Объект XmlNodeList, возвращенный этим метод будет действителен, пока базовый документ остается неизменным. Если базовый документ изменится, могут быть возвращены неожиданные результаты (исключение не будет выдано)».

Таким образом, то, что вы испытываете с вашим XmlNodeList, возвращенным из SelectNodes после того, как вы манипулируете документом, может не соответствовать вашим ожиданиям, но соответствует документации. Вам придется снова вызвать SelectNodes, чтобы получить новый XmlNodeList, если вы манипулируете документом.

На мой взгляд, разработчики реализации DOM в среде .NET совершили ошибку, использовав XmlNodeList в качестве абстрактного класса для конкретной реализации с совершенно другим поведением. Если вы используете, например. ChildNodes, то вы получаете «живой» список узлов в соответствии с тем, что требует спецификация W3C DOM, поэтому в этом случае изменение документа автоматически изменяет список узлов (при необходимости). Однако SelectNodes возвращает список узлов с совершенно другим поведением, как вы видели.

person Martin Honnen    schedule 23.03.2010