【问题标题】:How do I select with linq an attribute from an xml tag on the same level?如何使用 linq 从同一级别的 xml 标记中选择属性?
【发布时间】:2016-03-19 01:30:01
【问题描述】:

在下面的 xml 中,我尝试选择 FieldName UserName,并从不同属性中的同一级别获取“值”

我不确定我在 linq 查询中做错了什么

<?xml version="1.0"?>
<Objects>
  <Object>
    <Property Name="Value" Type="System.String">DeathStar</Property>
    <Property Name="FieldName" Type="System.String">Server</Property>
   </Object>
  <Object>
    <Property Name="Value" Type="System.String">Luke</Property>
    <Property Name="FieldName" Type="System.String">Username</Property>      
  </Object> 
 </Objects>

        var usernameValue =
            from v in
                from e in xd.Descendants().Elements()
                let p = e.Parent
                where
                    e.HasAttributes
                    && e.Name.LocalName.Equals("Property")
                    && e.Attribute("Name").Value.Equals("FieldName")
                    && e.Value.Equals("UserName")
                select p
            where
               v.HasAttributes
               && v.Name.LocalName.Equals("Property")
               && v.Attribute("Name").Value.Equals("Value")
            select v.Value;

【问题讨论】:

    标签: c# xml linq


    【解决方案1】:

    我建议将查询基于Object 元素,您可以从中检查FieldName 并返回相应的Value

    var usernameValue =
            from o in xd.Descendants("Object")
            where 
                o.Elements("Property")
                 .Where(p => (string)p.Attribute("Name") == "FieldName" && (string)p == "Username")
                 .Any()
            select 
                o.Elements("Property")
                 .Where(p => (string)p.Attribute("Name") == "Value")
                 .Select(p => (string)p)
                 .FirstOrDefault();
    

    还要注意 XML 是区分大小写的,所以Username,就像你的 XML 一样,不会被 UserName 匹配,就像你的 LINQ 一样。

    【讨论】:

      【解决方案2】:

      这会起作用,您必须过滤两次集合,第一次在对象级别,然后在属性值。

      var resultnode = doc.Descendants("Object")
          .Where(d=> d.Descendants("Property").Any(c=>c.Attribute("Name").Value == "FieldName") && d.Descendants("Property").Any(c=>c.Value == "Username"))
          .Descendants("Property")
          .Where(p=>p.Attribute("Name").Value == "Value")
          .FirstOrDefault();      
      

      现在可以使用访问值。

      if(resultnode != null)
      {
          resultnode.Value; // value  
      }
      

      工作Code

      【讨论】:

      • 谢谢我最终选择了这个 resharper,因为我抱怨用一个对 FirstOrDefault 的调用来替换,所以我删除了 Where 子句并将 where lambda 移动到 .FirstOrDefault 中。我认为它看起来更干净,因为不确定为什么 resharper 会抱怨。
      • 没问题,我很高兴问题得到解决,它有助于找到最佳解决方案。我建议用找到的解决方案写下答案,并将此问题标记为已回答,这可能对其他人有所帮助。
      猜你喜欢
      • 1970-01-01
      • 2011-03-09
      • 2013-03-09
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      相关资源
      最近更新 更多