使用Linq to XML,我如何选择恰好有x个父元素的元素?
本文关键字:元素 选择 XML to Linq 何选择 使用 | 更新日期: 2023-09-27 18:13:57
我试图在我的c#程序中使用Linq to XML从自动生成的XSD文件中提取元素名称。这意味着我不能基于元素名称/内容进行查询,而是需要根据元素在xsd中的位置查找元素。我试图用一个返回元素"深度"的函数来做到这一点。不知何故,如果我在查询中使用它,我不仅得到我需要的元素,而且得到所有底层元素/属性。我猜我需要一个"排除"功能在某种程度上,但我不知道如何做到这一点。这是我现在的代码:
static public void XsdReader()
{
var xsd = XDocument.Load(@"c:'XsdToLoad.xml");
var elementsAtDepthEight = from e in xsd.Descendants()
where GetElementDepth(e) == 8
select e;
foreach (var p in elementsAtDepthEight)
{
Console.WriteLine(p.ToString());
}
}
static int GetElementDepth(XElement element)
{
int result = 1;
//always return 1 as the root node has depth of 1.
//in addition, return the maximum depth returned by this method called on all the children.
if (element.Parent != null)
{
result += GetElementDepth(element.Parent);
}
return result;
}
衡量"深度"最简单的方法是计算祖先:
var elementsAtDepth8 = xsd.Descendants()
.Where(x => x.Ancestors().Count() == 8);
根本不需要编写自己的递归代码。
另一个稍微奇怪的替代方法是:
var elementsAtDepth = xsd.Elements()
.Elements()
.Elements()
.Elements()
.Elements()
.Elements()
.Elements()
.Elements();
你显然可以写一对递归方法来做这件事:
public static IEnumerable<XElement> ElementsAtDepth(this XNode node, int depth)
{
return node.Elements().ElementsAtDepth(depth - 1);
}
public static IEnumerable<XElement> ElementsAtDepth(
this IEnumerable<XElement> elements, int depth)
{
// TODO: Validate that depth >= 0
return depth == 0 ? elements : elements.Elements().ElementsAtDepth(depth - 1);
}