linq to xml获取所有子节点

发布于 2024-12-29 08:09:45 字数 1085 浏览 0 评论 0 原文

我正在尝试查询包含 WCF 条目的 web.Config 文件。

节点中,有一个我试图匹配的 name 属性。到目前为止,我的代码在进行匹配时已经有效,但我的问题是它只返回 1 个 节点。

例如,我可以有这样的 xml 片段:

<service name="a">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
<endpoint>3</endpoint>
</service>
<service name="b">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
</service>

每次获得匹配项时,我希望它显示该匹配项的所有 子节点。

这是我到目前为止的代码:

        IEnumerable<XElement> xmlURL =
            from el in xmlFile.Root.Descendants("service")
            where (string)el.Attribute("name") == serviceString
            select el.Element("endpoint");

        Console.WriteLine("Start: " + serviceString);
        foreach (XElement el in xmlURL)
        {
            Console.WriteLine(el);
        }
        Console.WriteLine("End: " + serviceString + "\n\n");

当前,当它匹配时,仅显示 1 个端点。

I'm trying to query a web.Config file that contains WCF entries.

In the <service> node there is a name attribute that I am trying to match off of. So far my code has worked when doing the matching, but my issue is that it only returns 1 of the <endpoint> nodes.

For example I could have this snippet of xml:

<service name="a">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
<endpoint>3</endpoint>
</service>
<service name="b">
<endpoint>1</endpoint>
<endpoint>2</endpoint>
</service>

Everytime I get a match I want it to display all the <endpoint> child nodes for that match.

This is the code I have so far:

        IEnumerable<XElement> xmlURL =
            from el in xmlFile.Root.Descendants("service")
            where (string)el.Attribute("name") == serviceString
            select el.Element("endpoint");

        Console.WriteLine("Start: " + serviceString);
        foreach (XElement el in xmlURL)
        {
            Console.WriteLine(el);
        }
        Console.WriteLine("End: " + serviceString + "\n\n");

Currently when it does the match only 1 endpoint is shown.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

開玄 2025-01-05 08:09:45

我想你想要这个:

    IEnumerable<XElement> xmlURL =
        from el in xmlFile.Root.Descendants("service")
        where (string)el.Attribute("name") == serviceString
        select el.Descendants("endpoint");

    Console.WriteLine("Start: " + serviceString);
    foreach (XElement el in xmlURL)
    {
        Console.WriteLine(el);
    }
    Console.WriteLine("End: " + serviceString + "\n\n");

注意我选择的是 el.Descendants() 而不是 Element() ,它只会返回第一个匹配项 (http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx)。

** 更新 **

我认为这就是您想要的,因为您只关心一个特定匹配。

IEnumerable<XElement> xmlURL = 
    (from el in doc.Root.Descendants("service")
    where el.Attribute("name").Value == serviceString
    select el).First().Descendants();

因此,正如编译器告诉您的那样,LINQ 查询的结果是 IEnumerable 的 IEnumerable,因此我采用 First() 结果,现在它给出了一个 IEnumerableIEnumerable,然后我们对其调用 Descendants(),这会为您提供端点 XElement 的 IEnumerable。

另请注意,这里我使用了 XAttributeValue 属性,您不能简单地将 XAttribute 转换为字符串,您必须使用Value 属性。我在最初的复制/粘贴答案中没有注意到这一点。

** UPDATE 2 **

上面的查询可能更容易理解,如下所示:

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();

** UPDATE 3 **

也有可能出现 NRE属性匹配,所以这可能是一个更好版本。 =)

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name") != null && x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();

I think you want this:

    IEnumerable<XElement> xmlURL =
        from el in xmlFile.Root.Descendants("service")
        where (string)el.Attribute("name") == serviceString
        select el.Descendants("endpoint");

    Console.WriteLine("Start: " + serviceString);
    foreach (XElement el in xmlURL)
    {
        Console.WriteLine(el);
    }
    Console.WriteLine("End: " + serviceString + "\n\n");

Notice I'm selecting el.Descendants() rather than Element() which will only ever return the first match (http://msdn.microsoft.com/en-us/library/system.xml.linq.xcontainer.element.aspx).

** UPDATE **

I think this is what you want, because you're only conerned with one specific match.

IEnumerable<XElement> xmlURL = 
    (from el in doc.Root.Descendants("service")
    where el.Attribute("name").Value == serviceString
    select el).First().Descendants();

So the result of the LINQ query is, as the compiler tells you, an IEnumerable of IEnumerables, so I take the First() result of which gives me now an IEnumerable<XElement>, and then we call Descendants() on that, which gives you an IEnumerable of the endpoint XElement's.

Also note here that I used the Value property of the XAttribute, you can't simply cast the XAttribute to a string, you have to use that Value property. I didn't catch that in my initial copy/paste answer.

** UPDATE 2 **

The above query can is probably a little easier to understand like this:

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();

** UPDATE 3 **

There is also the potential for a NRE on the attribute matching, so again this is probably an even better verison. =)

doc.Root.Descendants("service")
   .Where(x => x.Attribute("name") != null && x.Attribute("name").Value == serviceString)
   .First()
   .Descendants();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文