Удаление XML узлов путем сравнения элементов списка - PullRequest
1 голос
/ 08 мая 2020

Я работал над удалением нескольких узлов XML из строки XML. Мое требование - удалить узлы XML, соответствующие элементам списка. Я пытался получить дочерние узлы и проверить, есть ли имя дочернего узла в списке свойств. Я создал список свойств, представленных в классе MovieDetails.

public class MovieDetails 
    {
        public string MovieName { get; set; }
        public string MovieId { get; set; }
        public string MovieGenre { get; set; }
    }

My Xml:

<MovieContent>
  <MovieDetails>
      <MovieName>Movie_Name_1</MovieName>
      <MovieId>MovieId_1</MovieId>
      <MovieGenre>MovieGenre_3</MovieGenre>
      <AdditionalInformation>HAHAHHAHA</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
      <MovieName>Movie_Name_2</MovieName>
      <MovieId>MovieId_2</MovieId>
      <MovieGenre>MovieGenre_3</MovieGenre> 
      <AdditionalInformation>FOOOO</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
      <MovieName>Movie_Name_3</MovieName>
      <MovieId>MovieId_3</MovieId>
      <MovieGenre>MovieGenre_3</MovieGenre> 
      <AdditionalInformation></AdditionalInformation>
  </MovieDetails>
</MovieContent>

Я попытался использовать для l oop, но не смог получить желаемый результат. Но из приведенного ниже кода я мог удалить 1 узел каждый раз.

 var movieDetailsNode = xmlContent.DocumentElement.ChildNodes;
 var properties = typeof(MovieDetails).GetProperties().Select(x => x.Name).ToList();
    foreach (XmlNode node in movieDetailsNode )
    {
       var childNodeList = node.ChildNodes;
       for (int i = 0; i < childNodeList.Count; i++)
       {
           var childNodeName = childNodeList[0].Name;
           if (properties.Contains(childNodeName))
           {
               childNodeList[i].ParentNode.RemoveChild(childNodeList[i]);
           }
        }
     }

Может ли кто-нибудь помочь в достижении результата ниже xml

Результат XML:

<MovieContent>
  <MovieDetails>
      <AdditionalInformation>HAHAHHAHA</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
      <AdditionalInformation>FOOOO</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
      <AdditionalInformation></AdditionalInformation>
  </MovieDetails>
</MovieContent>

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Более простой способ - использовать LINQ to XML из пространства имен System.Xml.Linq для удаления узлов из вашей коллекции свойств. Здесь имеет смысл использовать HashSet<string>, поскольку имена должны быть уникальными, а время поиска должно быть постоянным, а не линейным.

var properties = typeof(MovieDetails)
    .GetProperties()
    .Select(x => x.Name)
    .ToHashSet();

// Or just var properties = new HashSet<string> { "MovieName", "MovieId", "MovieGenre" };

var doc = XElement.Load(@"C:\input.xml");

doc.Descendants("MovieDetails")
   .Elements()
   .Where(e => properties.Contains(e.Name.LocalName))
   .Remove();

doc.Save(@"C:\output.xml");

Пояснение

  • Получить MovieTitle узлы с Descendants().
  • Получить все дочерние элементы с Elements().
  • Отфильтровать несуществующие элементы в га sh установить с Enumerable.Where и HashSet<T>.Contains(T).
  • Удалить узлы из родительского узла с помощью Remove().

выход. xml

<MovieContent>
  <MovieDetails>
    <AdditionalInformation>HAHAHHAHA</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
    <AdditionalInformation>FOOOO</AdditionalInformation>
  </MovieDetails>
  <MovieDetails>
    <AdditionalInformation></AdditionalInformation>
  </MovieDetails>
</MovieContent>
0 голосов
/ 08 мая 2020

Это будет работать

            var movieDetailsNode = xmlContent.DocumentElement.ChildNodes;
            var properties = typeof(MovieDetails).GetProperties().Select(x => x.Name).ToList();
            foreach (XmlNode node in movieDetailsNode)
            {
                var childNodeList = node.ChildNodes;
                for (int i = 0; i < childNodeList.Count; i++)
                {
                   // replace '0' with 'i'
                    var childNodeName = childNodeList[i].Name;
                    if (properties.Contains(childNodeName))
                    {                       
                        childNodeList[i].ParentNode.RemoveChild(childNodeList[i]);
                        // add decrement of 'i' here
                        i--;
                    }
                }
            }
...