Как удалить XMLNode из XMLDocument, встречающегося на нескольких вложенных уровнях

У меня есть XML, который имеет узел, который повторяется на нескольких уровнях в файле с использованием C#.

Пример XML:

<books>
    <book>
        <title>The Walking Dead</title>
        <author>Test Name</author>
        <isbn>1239859895</isbn>
    </book>
    <book>
        <title>The Walking Dead</title>
        <author>
            <isbn>29893893893</isbn>
            <firstname>test1</firstname>
            <lastname>test</lastname>
        </author>
    </book>        
</books>

Я хочу удалить все узлы isbn из этого XML-документа независимо от его местоположения.

2 ответа

Решение

Как вы указали, что вы работаете с XmlDocument нужно убрать ребенка XmlElement узел через RemoveChild метод на родительском узле:

    string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
        <books>
            <book>
                <title>The Walking Dead</title>
                <author>Test Name</author>
                <isbn>1239859895</isbn>
            </book>
            <book>
                <title>The Walking Dead</title>
                <author>
                    <isbn>29893893893</isbn>
                    <firstname>test1</firstname>
                    <lastname>test</lastname>
                </author>
            </book>        
        </books>
        ";
    // Initialize and load the XmlDocument
    var doc = new XmlDocument();
    doc.LoadXml(xml);

    // Delete all XmlElements named "isbn".
    var list = doc.DocumentElement.GetElementsByTagName("isbn").OfType<XmlElement>().ToArray();
    foreach (var element in list)
    {
        var parent = element.ParentNode;
        if (parent != null)
            parent.RemoveChild(element);
    }
    var newXml = doc.OuterXml;
    Debug.WriteLine(newXml);

И вывод:

<?xml version="1.0" encoding="utf-16"?>
<books>
  <book>
    <title>The Walking Dead</title>
    <author>Test Name</author>
  </book>
  <book>
    <title>The Walking Dead</title>
    <author>
      <firstname>test1</firstname>
      <lastname>test</lastname>
    </author>
  </book>
</books>

Самый простой способ - использовать XDocument вместо XmlDocument. Используйте.Descendants(), чтобы найти все узлы с определенным именем / типом. Затем.Remove() им.

string xml = @"<books>
     <book>
         <title>The Walking Dead</title>
         <author>Test Name</author>
         <isbn>1239859895</isbn>
     </book>
     <book>
         <title>The Walking Dead</title>
         <author>
             <isbn>29893893893</isbn>
             <firstname>test1</firstname>
             <lastname>test</lastname>
         </author>
     </book>        
 </books>";

XDocument xdoc = XDocument.Parse(xml);
xdoc.Descendants("isbn").Remove();
string result = xdoc.ToString();

Но если вы хотите использовать XmlDocument, используйте этот код:

 XmlDocument xmldoc = new XmlDocument();
 xmldoc.LoadXml(xml);
 foreach (var node in new  List<XmlNode>(xmldoc.GetElementsByTagName("isbn")
                                         .OfType<XmlNode>()).Where(
                                         x => x.ParentNode != null))
 {
     node.ParentNode.RemoveChild(node);                      
 }

 string result = xmldoc.OuterXml;
Другие вопросы по тегам