如何获取XElement的位置(position())?

9
任何类似于 /NodeName/position() 的 XPath 表达式都可以给出节点相对于其父节点的位置。
在 XElement(Linq to XML)对象上没有可以获取元素位置的方法。有吗?
4个回答

11

实际上,NodesBeforeSelf().Count 不起作用,因为它获取的是所有类型为 XText 的元素。

问题是关于 XElement 对象的。所以我猜想这是

int position = obj.ElementsBeforeSelf().Count();

应该使用的内容,

感谢Bryant提供的指导。


6
你可以使用 NodesBeforeSelf 方法来实现这一点:
    XElement root = new XElement("root",
        new XElement("one", 
            new XElement("oneA"),
            new XElement("oneB")
        ),
        new XElement("two"),
        new XElement("three")
    );

    foreach (XElement x in root.Elements())
    {
        Console.WriteLine(x.Name);
        Console.WriteLine(x.NodesBeforeSelf().Count()); 
    }

更新:如果您只想要一个位置方法,只需添加一个扩展方法即可。
public static class ExMethods
{
    public static int Position(this XNode node)
    {
        return node.NodesBeforeSelf().Count();  
    }
}

现在你可以直接调用x.Position()函数。 :)

1
谢谢,x.NodesBeforeSelf().Count() 简单易用,太棒了。 但愿他们在 XElement 类的顶部称之为 Position。 - Vin
覆盖我的先前评论。请检查我下面的答案。 - Vin

1

实际上,在XDocument的Load方法中,您可以设置SetLineInfo的加载选项,然后将XElements强制转换为IXMLLineInfo以获取行号。

您可以像这样执行操作

var list = from xe in xmldoc.Descendants("SomeElem")
           let info = (IXmlLineInfo)xe
           select new 
           {
              LineNum = info.LineNumber,
              Element = xe
           }

但这仍然不能告诉您相对于节点父级的位置。它不只是行号吗? - Vin

0
static int Position(this XNode node) {
  var position = 0;
  foreach(var n in node.Parent.Nodes()) {
    if(n == node) {
      return position;
    }
    position++;
  }
  return -1;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接