gpt4 book ai didi

c# - 获取 XElement 的 XPath?

转载 作者:IT王子 更新时间:2023-10-29 03:55:33 25 4
gpt4 key购买 nike

我在文档深处有一个 XElement。给定 XElement(和 XDocument?),是否有扩展方法来获取其完整(即绝对,例如 /root/item/element/child)XPath?

例如myXElement.GetXPath()?

编辑:好吧,看来我忽略了一些非常重要的事情。哎呀!需要考虑元素的索引。有关建议的更正解决方案,请参阅我的最后一个答案。

最佳答案

扩展方法:

public static class XExtensions
{
/// <summary>
/// Get the absolute XPath to a given XElement
/// (e.g. "/people/person[6]/name[1]/last[1]").
/// </summary>
public static string GetAbsoluteXPath(this XElement element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}

Func<XElement, string> relativeXPath = e =>
{
int index = e.IndexPosition();
string name = e.Name.LocalName;

// If the element is the root, no index is required

return (index == -1) ? "/" + name : string.Format
(
"/{0}[{1}]",
name,
index.ToString()
);
};

var ancestors = from e in element.Ancestors()
select relativeXPath(e);

return string.Concat(ancestors.Reverse().ToArray()) +
relativeXPath(element);
}

/// <summary>
/// Get the index of the given XElement relative to its
/// siblings with identical names. If the given element is
/// the root, -1 is returned.
/// </summary>
/// <param name="element">
/// The element to get the index of.
/// </param>
public static int IndexPosition(this XElement element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}

if (element.Parent == null)
{
return -1;
}

int i = 1; // Indexes for nodes start at 1, not 0

foreach (var sibling in element.Parent.Elements(element.Name))
{
if (sibling == element)
{
return i;
}

i++;
}

throw new InvalidOperationException
("element has been removed from its parent.");
}
}

和测试:

class Program
{
static void Main(string[] args)
{
Program.Process(XDocument.Load(@"C:\test.xml").Root);
Console.Read();
}

static void Process(XElement element)
{
if (!element.HasElements)
{
Console.WriteLine(element.GetAbsoluteXPath());
}
else
{
foreach (XElement child in element.Elements())
{
Process(child);
}
}
}
}

和示例输出:

/tests/test[1]/date[1]
/tests/test[1]/time[1]/start[1]
/tests/test[1]/time[1]/end[1]
/tests/test[1]/facility[1]/name[1]
/tests/test[1]/facility[1]/website[1]
/tests/test[1]/facility[1]/street[1]
/tests/test[1]/facility[1]/state[1]
/tests/test[1]/facility[1]/city[1]
/tests/test[1]/facility[1]/zip[1]
/tests/test[1]/facility[1]/phone[1]
/tests/test[1]/info[1]
/tests/test[2]/date[1]
/tests/test[2]/time[1]/start[1]
/tests/test[2]/time[1]/end[1]
/tests/test[2]/facility[1]/name[1]
/tests/test[2]/facility[1]/website[1]
/tests/test[2]/facility[1]/street[1]
/tests/test[2]/facility[1]/state[1]
/tests/test[2]/facility[1]/city[1]
/tests/test[2]/facility[1]/zip[1]
/tests/test[2]/facility[1]/phone[1]
/tests/test[2]/info[1]

这应该可以解决这个问题。不?

关于c# - 获取 XElement 的 XPath?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/451950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com