0

我有一个 xml 文档,其中一个节点包含一个用户节点列表,一个节点包含一个包含用户列表的组。我想从 users 集合中删除 groups 集合中没有匹配 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();

这可能吗?

4

3 回答 3

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();
于 2013-10-16T14:10:38.993 回答
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();
于 2013-10-16T14:07:47.443 回答
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>...
于 2013-10-16T14:24:04.703 回答