通过比较列表项删除 XML 个节点
Removing XML Nodes by Comparing the List items
我一直致力于从 XML 中删除几个 XML 节点 string.My 要求是删除与列表项匹配的 XML 节点。我试图获取 childNodes 并检查 childNode 的名称是否在属性列表中。我已经生成了 MovieDetails class 中存在的属性列表。
public class MovieDetails
{
public string MovieName { get; set; }
public string MovieId { get; set; }
public string MovieGenre { get; set; }
}
MyXml:
<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>
我尝试使用 for 循环但无法从下面的代码中获得我想要的 result.But 我每次都可以在 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>
这会起作用
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--;
}
}
}
一种更简单的方法是使用 LINQ to XML from the 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");
说明
- 使用
Descendants()
获取MovieTitle
个节点。
- 获取所有带
Elements()
的子元素。
- 用
Enumerable.Where
and HashSet<T>.Contains(T)
过滤掉散列集中不存在的元素。
- 使用
Remove()
从父节点中删除节点。
output.xml
<MovieContent>
<MovieDetails>
<AdditionalInformation>HAHAHHAHA</AdditionalInformation>
</MovieDetails>
<MovieDetails>
<AdditionalInformation>FOOOO</AdditionalInformation>
</MovieDetails>
<MovieDetails>
<AdditionalInformation></AdditionalInformation>
</MovieDetails>
</MovieContent>
我一直致力于从 XML 中删除几个 XML 节点 string.My 要求是删除与列表项匹配的 XML 节点。我试图获取 childNodes 并检查 childNode 的名称是否在属性列表中。我已经生成了 MovieDetails class 中存在的属性列表。
public class MovieDetails
{
public string MovieName { get; set; }
public string MovieId { get; set; }
public string MovieGenre { get; set; }
}
MyXml:
<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>
我尝试使用 for 循环但无法从下面的代码中获得我想要的 result.But 我每次都可以在 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>
这会起作用
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--;
}
}
}
一种更简单的方法是使用 LINQ to XML from the 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");
说明
- 使用
Descendants()
获取MovieTitle
个节点。 - 获取所有带
Elements()
的子元素。 - 用
Enumerable.Where
andHashSet<T>.Contains(T)
过滤掉散列集中不存在的元素。 - 使用
Remove()
从父节点中删除节点。
output.xml
<MovieContent>
<MovieDetails>
<AdditionalInformation>HAHAHHAHA</AdditionalInformation>
</MovieDetails>
<MovieDetails>
<AdditionalInformation>FOOOO</AdditionalInformation>
</MovieDetails>
<MovieDetails>
<AdditionalInformation></AdditionalInformation>
</MovieDetails>
</MovieContent>