我有一个xml文档,其中包含一个包含用户节点列表的节点,以及一个包含具有用户列表的组的节点。我想删除users集合中没有匹配的dn的所有节点。
作为下面简化结构中的一个例子,我试图删除所有deleteme,用户节点。
<?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>
下面的代码删除了syncdata / users集合中的所有项目,我需要执行与不存在的SQL类似的操作。
System.Xml.Linq.XDocument xdoc
xdoc.Descendants("users").Where(F => F.Parent.Name == "syncdata").Descendants("user").Where(u => u.Parent.Name == "users").Remove();
这可能吗?
答案 0 :(得分:4)
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();
答案 1 :(得分:3)
获得2个收藏的简单且更可靠的方式:
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();
答案 2 :(得分:0)
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>...