LinqToXml:根据管理层次结构对用户节点重新排序
本文关键字:新排序 排序 节点 用户 管理 层次结构 LinqToXml | 更新日期: 2023-09-27 18:35:50
我有一个来自LDAP(活动目录)的用户及其经理的输出xml,如下所示。 我需要对用户重新排序,以便在创建用户时按管理层次结构的顺序创建用户。"用户"和"管理器"子节点中的 DN 字段是链接值。这样,当它们由我们的用户导入例程处理时,我们不必在尚未创建管理器时满足向用户分配管理器的需求。这在Linqtoxml上可能吗?
<?xml version="1.0" encoding="utf-8"?>
<syncdata>
<users>
<user>
<dn>User2</dn>
<manager><dn>User1</dn></manager>
</user>
<user>
<dn>User1</dn>
<manager><dn>User5</dn></manager>
</user>
<user>
<dn>User4</dn>
<manager><dn>User1</dn></manager>
</user>
<user>
<dn>User5</dn>
<manager><dn>User3</dn></manager>
</user>
<user>
<dn>User3</dn>
<manager><dn></dn></manager>
</user>
</users>
</syncdata>
更新:重新格式化了 XML,因为建议部分有效。 它以前是无效的,因为有一个循环引用。
var element = XElement.Load(yourXmlPath);
var ordered=element.Element("users").Elements().OrderBy(u => u.Element("manager").Element("dn").Value);
element.Element("users").ReplaceAll(ordered);
此选项将为您提供一个排序IOrderedEnumerable
,每个用户的xml和managerId分别。这种变化应该会给你很大的灵活性:
var sortedUsers =
yourRootXElement.Element("users")
.Elements()
.Select(usr =>
new {
managerId = usr.Element("manager")
.Element("dn")
.Value,
user = usr
})
.OrderBy(user => user.managerId);
更新:
根据其他答案之一下的评论,您似乎想"递归"(有点)对此进行重新排序。
最初,我认为使用 Linq 并不容易 - 除非您可以选择操作原始 XML,否则最好为此编写递归算法。
但是,如果,您可以向XML中的每个用户添加一个字段depth
,使其看起来像这样..:
<syncdata>
<users>
<user>
<dn>User2</dn>
<manager><dn>User1</dn></manager>
<depth>2</depth>
</user>
<user>
<dn>User1</dn>
<manager><dn>User5</dn></manager>
<depth>1</depth>
</user>
<user>
<dn>User4</dn>
<manager><dn>User1</dn></manager>
<depth>2</depth>
</user>
<user>
<dn>User5</dn>
<manager><dn>User3</dn></manager>
<depth>1</depth>
</user>
<user>
<dn>User3</dn>
<manager><dn></dn></manager>
<depth>0</depth> <!-- Note: Root element in hierarchy! -->
</user>
</users>
</syncdata>
。那么也许您可以按如下方式订购它?
var sortedUsers =
yourRootXElement.Element("users")
.Elements()
.Select(usr =>
new {
userId = usr.Element("dn").Value,
managerId = usr.Element("manager")
.Element("dn")
.Value,
depth = usr.Element("depth")
.Value,
userData = usr
})
.OrderBy(user => user.depth)
.ThenBy(user => user.managerId);
注意:这应该按层次结构中的"报告级别"对它们进行排序,但不会显示他下面列出的经理下的人员 - 即:所有向高层经理报告的人都将首先显示,然后是所有向二级经理报告的人,等等......