C# LinqtoXML:如何删除值不在另一个集合中的节点
我有一个xml文档,其中一个节点包含用户节点列表,另一个节点包含具有用户列表的组。我想从users集合中删除groups集合中没有匹配dn的所有节点 作为下面简化结构中的一个示例,我试图删除所有deleteme、user节点C# LinqtoXML:如何删除值不在另一个集合中的节点,c#,xml,linq,linq-to-xml,C#,Xml,Linq,Linq To Xml,我有一个xml文档,其中一个节点包含用户节点列表,另一个节点包含具有用户列表的组。我想从users集合中删除groups集合中没有匹配dn的所有节点 作为下面简化结构中的一个示例,我试图删除所有deleteme、user节点 <?xml version="1.0" encoding="utf-8"?> <syncdata > <users > <user> <dn>deleteme1</dn>
<?xml version="1.0" encoding="utf-8"?>
<syncdata >
<users >
<user>
<dn>deleteme1</dn>
</user>
<user>
<dn>deleteme2</dn>
</user>
<user>
<dn>deleteme3</dn>
</user>
<user>
<dn>JohnSmith</dn>
</user>
</users>
<groups>
<group name="group2">
<users>
<user>
<dn>JohnSmith</dn>
</user>
</users>
</group>
<group name="group1">
<users>
<user>
<dn>JohnDoe</dn>
</user>
<user>
<dn>JohnnyMorris</dn>
</user>
</users>
</group>
</groups>
</syncdata>
这是可能的吗?获取两个系列的简单且更可靠的方法:
var users = xDoc.Element("syncdata").Element("users")
.Elements("user").ToList(); // cache in list
var userNamesInGroups = xDoc.Element("syncdata").Element("groups")
.Descendants("user").Element("dn").Value;
var usersToDelete = users
.Where(u => ! userNamesInGroups.Contains(u.Element("dn").Value));
foreach(var user in usersToDelete)
user.Remove();
我把它扩展了一点。您可能可以将其滚动到更少的Linq语句中,但请注意ToList。你需要一个foreach来做Removesthanks,顺便问一下,有没有一种方法可以只改变一个字符就对一篇文章进行编辑?您的示例具有常量,试图将其更改为Contains,并且一次更改的字符太少
var users = xDoc.Element("syncdata").Element("users")
.Elements("user").ToList(); // cache in list
var userNamesInGroups = xDoc.Element("syncdata").Element("groups")
.Descendants("user").Element("dn").Value;
var usersToDelete = users
.Where(u => ! userNamesInGroups.Contains(u.Element("dn").Value));
foreach(var user in usersToDelete)
user.Remove();
var xDoc = XDocument.Load(fname);
HashSet<string> set = new HashSet<string>(xDoc.Root.Element("groups")
.Descendants("dn")
.Select(dn => (string)dn));
foreach (var user in xDoc.Root.Element("users").Elements("user").ToList())
{
if(!set.Contains(user.Element("dn").Value))
user.Remove();
}
var newXml = xDoc.ToString();
string xml = @"<?xml version='1.0' encoding='utf-8'?>
<syncdata >
<users >
<user>
<dn>JohnDoe</dn>
</user>
<user>
<dn>deleteme2</dn>
</user>
<user>
<dn>deleteme3</dn>
</user>
<user>
<dn>JohnSmith</dn>
</user>
</users>
<groups>
<group name='group2'>
<users>
<user>
<dn>JohnSmith</dn>
</user>
</users>
</group>
<group name='group1'>
<users>
<user>
<dn>JohnDoe</dn>
</user>
<user>
<dn>JohnnyMorris</dn>
</user>
</users>
</group>
</groups>
</syncdata> ";
var doc = XDocument.Parse(xml);
var groupUsersList = doc.Root.Element("groups")
.Descendants("dn")
.Select(x => (string)x)
.ToList();
var users = doc.Root.Element("users").Elements("user").ToList();
foreach (var user in users )
{
if(!groupUsersList.Contains(user.Element("dn").Value))
user.Remove();
}
Console.WriteLine(doc.ToString());
// prints <syncdata>
// <users>
// <user>
// <dn>JohnDoe</dn>
// </user>
// <user>
// <dn>JohnSmith</dn>
// </user>
// </users>
// <groups>...