Get Attributes Name and value of an element in C # via System.Linq

I have one custom config file.

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

I read this file through the implementation of the IConfigurationHandler interface. When I read the childNode attributes of the Detail element. It brings me back below the result in the Immediate Window IDE.

 elem.Attributes.ToObjectArray() {object[2]} [0]: {Attribute, Name="key", Value="Main"} [1]: {Attribute, Name="value", Value="web"} 

When I try to write on the console

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

he brings me back

 Value : 'System.Configuration.ConfigXmlAttribute' 

elem.Attributes.Item(1) method gives me a name and value, but here I need to pass the value of the attribute index, which I do not know at the moment.

I want to get the name and value of an attribute using a LINQ query and an individual console display for each childNode attribute as follows:

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

How can i achieve this?

+8
c # xml linq linq-to-xml
source share
4 answers

If you want to use this Xml Library , you can get all students and their data using this code:

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

Then, to iterate over them, use:

 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)); } 
+3
source share

You can use Linq Select and string.Join to get the result you want.

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

This will cause all the attributes of the child elements of the Detail element to be specified in your question.

 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)); } 
+2
source share

If you have Attributes in object[] , as you wrote, you can make fun of

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

then the problem is that you have anonymous types whose names cannot be easily extracted.

Take a look at this code (you can paste it into the main () method of the LinqPad editor window to execute it):

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

Since you cannot access the Name and Value properties of the Attributes variable inside the object [] array, because the compiler hides them from you, the trick here is to use the Join (",", a) method to get around this limitation.

All you have to do after this is trim and split the resulting string and finally create a new object with Value and Name . You can try if you uncomment the line linq.Dump (); in LinqPad - it returns what you want, and, in addition, it is requested by Linq operators.

0
source share

All Articles