How to write a single LINQ to XML query to iterate through all the child elements & all the attributes of the child elements?

I am developing asp.net mobile application. I am using XML as a database. I am querying on the XML to access the required elements & attributes by using LINQ to XML in .net. I have the follwing part in my XML file.

<VALVES>
     <VALVE NAME="PWV">
      <DISPLAY-NAME>
       Production Master Valve
      </DISPLAY-NAME>
      <COMMANDS USE-TEMPLATE="TRUE" TEAMPLATE-NAME="ValveCommands.xml"></COMMANDS>
    </VALVE>
    <VALVE NAME="PMV" >
     <DISPLAY-NAME>
      Production Wing Valve
     </DISPLAY-NAME>
     <COMMANDS USE-TEMPLATE="TRUE" TEAMPLATE-NAME="ValveCommands.xml"></COMMANDS>
    </VALVE>
</VALVES>

In the above XML file I can access the the child element node ‘VALVE’ & its attribute ‘NAME’ dynamically without explicitly specifying the name of the attribute by using following code. Thus as any new attribute is added in the child node ‘VALVE’ I can access it without modifying my existing code. For such logic I am using following code. In the following code ValvesProperties is the Hashtable which is defined in the class ‘Valves’.

 static int count = 0;
 List<Valves> LstValves = new List<Valves>();

 string AttName = null;
 string AttValue = null;

 XDocument FieldDef = XDocument.Load(@"F:Shailesh from user OPCXMLKK3.xml");
 XElement FieldRoot = FieldDef.Element("KK");

 count = FieldRoot.Element("FIELD-DEFINITION").Element("VALVES").Elements("VALVE").Count();
 Valves[] Valveobj = new Valves[count];

 count = 0;

 foreach (var element in FieldRoot.Element("FIELD-DEFINITION").Element("VALVES").Elements())
 {
     Valveobj[count] = new Valves();

     foreach (var attribute in element.Attributes())
     {
         AttName = attribute.Name.ToString();
         AttValue = attribute.Value.ToString();
         Valveobj[count].ValvesProperties.Add(AttName, AttValue);
         LstValves.Add(Valveobj[count]);
     }

     count++;
  }

return LstValves;

The similar logic I need for the above defined XML part. In the above XML I want to write the LINQ to XML query which can access the NAME attribute of the ‘VALVE’ node (<VALVE NAME="PWV">), then it should access the text between ‘DISPLAY-NODE’ (<DISPLAY-NAME> Production Master Valve </DISPLAY-NAME>), & then it should access the all the attributes of the ‘COMMAND’ node dynamically ( <COMMANDS USE-TEMPLATE="TRUE" TEAMPLATE-NAME="ValveCommands.xml"></COMMANDS>). All these I want dynamically without explicitly specifying the name of the child node as well as name of their attributes ( similar to the way I written the above query ) Can we write such a code by using LINQ to XML ? It will be better if we can write code for above issue in a single logic ( similar to the way I written the above query ). Can you provide me the any code or link through which I can resolve the above issue ?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You could just iterate through all the elements and retrieve the attributes for each:

var allDescendants = myElement.DescendantsAndSelf();
var allDescendantsWithAttributes = allDescendants.SelectMany(elem =>
    new[] { elem }.Concat(elem.Attributes().Cast<XContainer>()));

foreach (XContainer elementOrAttribute in allDescendantsWithAttributes)
{
    // ...
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x