【问题标题】:Select Nodes with specific attribute using Linq使用 Linq 选择具有特定属性的节点
【发布时间】:2014-09-03 06:01:21
【问题描述】:

我希望我的 Linq 语句仅获取以下示例中具有 name="Required" 的自定义字段

   <root>
    <appinfo>
        <application app_id=1234 app_name="SomeName">
        <customfield name="Required" value="123" />
        <customfield name="Not Required" value="234" />
        <customfield name="Not Required" value="345" />
        <customfield name="Not Required" value="456" />
        <customfield name="Not Required" value="678" />
        </application>
    </appinfo>
    ...
    </root>

1234,SomeName,123在这种情况下需要选择

以下是我尝试过的陈述。评论的 Where 不起作用

 var appAI =
        from appinfo in doc.Root.Elements()

        let application = appinfo.Elements().First()
        let custom_field = application.Descendants()

        //.Where(x => (string)x.Attribute("name") == "Required" && (string)x.Attribute("value").Value !="" )
        select new
        {
            app_id = (string)application.Attribute("app_id"),
            app_name = (string)application.Attribute("app_name"),
            app_AI = custom_field

        };

【问题讨论】:

  • 不应该是x.Attribute("name") == "Required"x.Attribute("name").Value == "Required"
  • 我都试过了。没有运气..

标签: c# xml linq


【解决方案1】:

这似乎对我有用:

var results = 
    from appInfo in d.Elements()
    let application = appInfo.Elements().First()
    let custom_field = application.Descendants()
        .Where(x => x.Attribute("name").Value == "Required" && x.Attribute("value").Value != "")
        .SingleOrDefault()
    select new
    {
        app_id = application.Attribute("app_id").Value,
        app_name = application.Attribute("app_name").Value,
        app_AI = custom_field.Attribute("value").Value
    };

我认为您的主要问题是查看d.Root.Elements 而不仅仅是d.Elements

示例: https://dotnetfiddle.net/XVM1qz

【讨论】:

  • 我在我的问题中错过了一个根标签。抱歉.. 我尝试使用 d.Root.Elements()。我得到对象引用未设置错误
  • 奇怪..当我尝试使用您的小提琴链接时..即使添加了root,它也可以正常工作
  • 我发现了错误。这是因为,很少有节点没有应用程序的结束标签。在这里复制了同样的dotnetfiddle.net/YUoL4N
【解决方案2】:

看看这是否可行。请注意,您可以直接从 IEnumerable&lt;T&gt; 链接“元素”和其他一些扩展方法,以使其更简单。

from app in doc.Elements("appinfo").Elements("application")
from cf in app.Elements("customfield")
where (string)cf.Attribute("name") == "Required"
select new
{
    app_id = (string)app.Attribute("app_id"),
    app_name = (string)app.Attribute("app_name"),
    app_AI = (string)cf.Attribute("value")
};

Descendants 很少有用,因为它可以隐藏文档中潜在的结构问题。除非我在其他地方执行验证(例如使用 XSD),否则我不会使用它。

【讨论】:

  • 它工作了..有一个小的改动。 .对于我的新 XML,它必须是 doc.Root.Elements 。此外,添加了 cf.Attribute("value").Value != "" 条件
猜你喜欢
  • 2021-07-31
  • 2011-01-30
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
相关资源
最近更新 更多