Попытка использовать RemoveChild() в XmlNodeList портит мою коллекцию XmlNode.
-
21-09-2019 - |
Вопрос
Я пытаюсь удалить определенный узел из списка XmlNodeList с именем listaWidths.Этот конкретный список содержит 5 элементов, прежде чем я использую RemoveChild().Но после оператора RemoveChild() в списке остается только один элемент.
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.Конкретный 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>
(...)
Я перепробовал все возможные комбинации, но безуспешно.Что я делаю не так?Спасибо.
Решение
Документация SelectNodes ясно говорит:«Объект XmlNodeList, возвращаемый этим методом, будет действительным, пока базовый документ остается неизменным.Если базовый документ изменится, могут быть возвращены неожиданные результаты (исключения не будут выданы)».
Поэтому то, что вы испытываете с XmlNodeList, возвращенным из SelectNodes после манипуляций с документом, может быть не таким, как вы ожидаете, но соответствует документации.Вам придется снова вызвать SelectNodes, чтобы получить новый XmlNodeList, если вы манипулируете документом.
На мой взгляд, разработчики реализации DOM в .NET Framework допустили ошибку, использовав XmlNodeList в качестве абстрактного класса для конкретной реализации с совершенно другим поведением.Если вы используете, например.ChildNodes, то вы получаете «живой» список узлов в соответствии с требованиями спецификации W3C DOM, поэтому в этом случае изменение документа автоматически меняет список узлов (при необходимости).Однако SelectNodes возвращает список узлов с совершенно другим поведением, как вы уже видели.