【问题标题】:Get attributes Name and Value of element in C# through System.Linq通过 System.Linq 获取 C# 中元素的属性名称和值
【发布时间】:2012-05-24 07:53:14
【问题描述】:

我有一个自定义配置文件。

<Students>
 <student>
   <Detail Name="abc" Class="1st Year">
       <add key="Main" value="web"/>
       <add key="Optional" value="database"/>
   </Detail>
 </student>
</Students>

我通过 IConfigurationHandler 接口实现读取了这个文件。 当我阅读 Detail 元素的 childNode 属性时。它将下面的结果返回到 IDE 的即时窗口中。

elem.Attributes.ToObjectArray()

{object[2]}
    [0]: {Attribute, Name="key", Value="Main"}
    [1]: {Attribute, Name="value", Value="web"}

当我尝试在控制台上写字时

 Console.WriteLine("Value '{0}'",elem.Attributes.ToObjectArray());

它确实返回了我

Value : 'System.Configuration.ConfigXmlAttribute'

elem.Attributes.Item(1) 方法为我提供了名称和值的详细信息,但在这里我需要传递我目前不知道的属性的索引值。

我想通过 LINQ 查询 获取属性的名称和值,并在控制台上为每个 childNode 属性单独显示如下:

Value : Name="Key" and Value="Main"
        Name="value", Value="web"

我怎样才能做到这一点?

【问题讨论】:

  • 你想在这里做什么?修复 Console.Writeline?您能否发布更多代码以便我们了解流程?

标签: c# xml linq linq-to-xml


【解决方案1】:

如果您想使用此Xml Library,您可以使用此代码获取所有学生及其详细信息:

XElement root = XElement.Load(file); // or .Parse(string)
var students = root.Elements("student").Select(s => new
{
    Name = s.Get("Detail/Name", string.Empty),
    Class = s.Get("Detail/Class", string.Empty),
    Items = s.GetElements("Detail/add").Select(add => new
    {
        Key = add.Get("key", string.Empty),
        Value = add.Get("value", string.Empty)
    }).ToArray()
}).ToArray();

然后迭代它们使用:

foreach(var student in students)
{
    Console.WriteLine(string.Format("{0}: {1}", student.Name, student.Class));
    foreach(var item in student.Items)
        Console.WriteLine(string.Format("  Key: {0}, Value: {1}", item.Key, item.Value));
}

【讨论】:

    【解决方案2】:

    你可以使用 Linq Selectstring.Join 来获得你想要的输出。

    string.Join(Environment.NewLine, 
        elem.Attributes.ToObjectArray()
            .Select(a => "Name=" + a.Name + ", Value=" + a.Value)
    )
    

    【讨论】:

    • String.Format() 会是更好的选择:.Select(a =&gt; string.format("Name={0}, Value={1}",a.Name,a.Value))
    • elem.Attributes.ToObjectArray() .Select(a => "Name=" + a.Name + ", Value=" + a.Value);不要在这里给出 a.Name 和 a.Value 。我已经尝试过了,但它没有返回 a.Name 和 a.Value。
    【解决方案3】:

    这将获取您在问题中陈述的 Detail 元素的子元素的所有属性。

    XDocument x = XDocument.Parse("<Students> <student> <Detail Name=\"abc\" Class=\"1st Year\"> <add key=\"Main\" value=\"web\"/> <add key=\"Optional\" value=\"database\"/> </Detail> </student> </Students>");
    
    var attributes = x.Descendants("Detail")
                      .Elements()
                      .Attributes()
                      .Select(d => new { Name = d.Name, Value = d.Value }).ToArray();
    
    foreach (var attribute in attributes)
    {
         Console.WriteLine(string.Format("Name={0}, Value={1}", attribute.Name, attribute.Value));
    }
    

    【讨论】:

      【解决方案4】:

      如果您在object[] 中具有属性,就像您所写的那样,可以被

      var Attributes = new object[]{
          new {Name="key", Value="Main"},
          new {Name="value", Value="web"}
      };
      

      那么问题是您有匿名类型,其名称无法轻松提取。

      看看这段代码(你可以将它粘贴到 LinqPad 编辑器窗口的 main() 方法中来执行它):

      var linq=from a in Attributes
      let s = string.Join(",",a).TrimStart('{').TrimEnd('}').Split(',')
      select new 
      {
          Value = s[0].Split('=')[1].Trim(),
          Name = s[1].Split('=')[1].Trim()
      };
      //linq.Dump();
      

      由于您无法访问 object[] 数组中的变量 Attributes 的 Name 和 Value 属性,因为编译器会将它们隐藏起来,所以诀窍就在这里使用 Join(",", a) 方法来绕过这个限制。

      之后你需要做的就是trimsplit生成的字符串,最后用Value创建一个新对象名称属性。 如果您取消注释 LinqPad 中的 linq.Dump(); 行,您可以尝试一下 - 它返回您想要的内容,并且可以通过 Linq 语句查询。

      【讨论】:

        猜你喜欢
        • 2011-11-30
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 2016-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多