如何记录xml树中两个节点之间的路径?

时间:2016-01-07 19:50:51

标签: c# xml recursion tree nodes

我希望能够记录从xml树中的某个节点到另一个节点需要采取的路径。用这个图代替XML树:

   A
  / \
 B   C - D
/   / \
E  F   G

例如,如果我想记录从D到E的路径,路径将上升到父C,上升到父A,下到子B,下到子E.所以也许实际记录路径是节点D - >;节点C - >节点A - >节点B - >节点E.我怎么能记录这样的路径?

1 个答案:

答案 0 :(得分:1)

基本上,您希望创建从每个节点到根的路径。然后比较从根开始的两个路径中的节点并找到最后一个匹配。这是共同的祖先。有了它,你可以截断每个路径,只是将它们连接在一起。

public static string CreatePath(XElement from, XElement to)
{
  var fromToRoot = from.PathToRoot();
  var rootToTo = to.PathToRoot().Reverse();

  var commonAncestor = rootToTo.Zip(fromToRoot.Reverse(), Tuple.Create)
    .TakeWhile(nodes => nodes.Item1 == nodes.Item2)
    .Select(nodes => nodes.Item1)
    .LastOrDefault();

  if (commonAncestor == null) return "Not connected";

  return string.Join(
    "->",
    fromToRoot.TakeWhile(node => node != commonAncestor)
      .Concat(rootToTo.SkipWhile(node => node != commonAncestor))
      .Select(n => n.Name));
}

public static IEnumerable<XElement> PathToRoot(this XElement from)
{
  yield return from;
  var fromParent = from.Parent;
  while (fromParent != null)
  {
    yield return fromParent;
    fromParent = fromParent.Parent;
  }
}