【问题标题】:Using Linq to XML, how can I select the elements that have exactly x number of parent elements?使用 Linq to XML,如何选择具有正好 x 个父元素的元素?
【发布时间】:2015-09-22 08:52:20
【问题描述】:

我正在尝试在我的 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;
        }

【问题讨论】:

    标签: c# xml linq xsd


    【解决方案1】:

    测量“深度”的最简单方法是数ancestors

    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);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2011-07-04
      • 1970-01-01
      • 2010-12-17
      相关资源
      最近更新 更多