2014-02-08 8 views
0

Мне нужна функция, которая может удалить все дочерние узлы определенного узла. Но только дочерние узлы, а не атрибуты. В System.XML есть стандартная функция для удаления всех дочерних элементов, но она также удаляет все атрибуты, которые у меня есть.Xml Удалить дочерние элементы, но не атрибуты

В результате я пишу свое собственное funcrtion, которое принимает в качестве параметров xmlDocument, мой родительский узел (сектор) и переменную bool toRemoveAttributes. В этом случае я беру все атрибуты в один XmlAttributeCollection, а затем использую функцию RemoveAll.

public void RemoveChild(XmlDocument xd, string sectorName, bool removeAttributes) 
{ 
    XmlElement sector; 
    if (sectorName == "root") 
     sector = xd.DocumentElement; 
    else 
     sector = (XmlElement)xd.GetElementsByTagName(sectorName)[0]; 

    XmlAttributeCollection atr = sector.Attributes;    
    sector.RemoveAll(); 
    if(!removeAttributes) 
    { 
     for (int i = 0; i < atr.Count; i++) 
      sector.SetAttribute(atr[i].Name, atr[i].Value); 
    } 
} 

В результате мои атрибуты по-прежнему удаляются. Когда я отлаживал свой код, я увидел, что после RemoveAll() также все удалено из моего 'atr' colection.

ответ

0

Ответ и решение проблемы здесь уже здесь:
How to remove all child nodes of an XmlElement, but keep all attributes?.


Я просто хочу добавить пару заметок о вашей конкретной ситуации.

Garath предоставил подробное объяснение, в том числе то, что вызов не делает внутренне:

// Removes all specified attributes and children of the current node. 
// Default attributes are not removed. 
public override void RemoveAll() 
{ 
    base.RemoveAll(); 
    this.RemoveAllAttributes(); 
} 

Поскольку ваша atr переменная ссылается sector.Attributes и предыдущий метод просто удалены атрибуты из sector, atr больше не имеет атрибутов или. Итак, atr.Count == 0 и цикл никогда не запускается. Вы можете попробовать проверить это, поставив точку останова на sector.SetAttribute... и посмотреть, попадает ли он.

См. other answer в этом вопросе относительно решения, которое вы могли бы использовать вместо этого.


Есть несколько других звонков вы могли бы сделать, что бы иметь такой же эффект RemoveAll без вызова RemoveAllAttributes, но могут быть непреднамеренные побочные эффекты, так что я бы придерживаться с ответом на другой пост.

sector.InnerXml = ""; 

Или:

sector.IsEmpty = true; 
Смежные вопросы