Bandoth
Bandoth

Reputation: 87

C# Linq to XML - Parse Nested Object List

I currently have a XML file format that goes something like this (whitespace and ellipses added for readability):

<root>
    <Module>          //Start with list of Modules
        <ModuleParams>
        </ModuleParams>
    </Module>
    ...

    <DetectLine>      //Now a list of DetectLines
        <DetectLineParams>
        </DetectLineParams>

        <Channels>    //List of Channels embedded in each DetectLine
            <Channel>
                <ChannelParams>
                </ChannelParams>
            </Channel>
            ...

        </Channels>
    </DetectLine>
    ...

</root>

Classes structured as follows:

public class Module
{
    public ModuleParams { get; set; }
}

public class DetectLine
{
    public DetectLineParams { get; set; }
    public List<Channel> Channels { get; set; }
}

public class Channel
{
    public ChannelParams { get; set; }
}

The list of Modules and DetectLines are easy to parse with Linq to XML. However, parsing the Channel list for each DetectLine is not as apparent to me. Can this even be done with Linq to XML? I would prefer not having to restructure things to work with a XMLSerializer.

Initial Code (openXML is a OpenFileDialog. Already checked for good filename):

List<Module> myModules;
List<DetectLine> myDetectLines;
XDocument config = XDocument.Load(openXML.FileName);

myModules =
         (from myElements in config.Descendants("Module")
          select new Module()
          {
              ModuleParam1 = (string)myElements.Element("ModuleParam1"),
              ModuleParam2 = (string)myElements.Element("ModuleParam2"),
              ...
          }).ToList<Module>();

myDetectLines =
          (from myElements in config.Descendants("DetectLine")
           select new DetectLine()
           {
              DetectLineParam1 = (string)myElements.Element("ModuleParam1"),
              DetectLineParam2 = (string)myElements.Element("ModuleParam2"),
              ...

              // ?? Add Channels list here somehow...
           }).ToList<DetectLine>();

Upvotes: 3

Views: 3337

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167551

With

XElement detectLine = XElement.Parse(@"<DetectLine>      
        <DetectLineParams>
        </DetectLineParams>

        <Channels>    
            <Channel>
                <ChannelParams>
                </ChannelParams>
            </Channel>
            ...

        </Channels>
    </DetectLine>
");

you can do e.g.

DetectLine dl1 = new DetectLine() {
  DetectLineParams = ...,
  Channels = (from channel in detectLine.Element("Channels").Element("Channel")
             select new Channel() {
                 ChannelParams = new ChannelParams() { ... = channel.Element("ChannelParams").Value }
             }).ToList();

We really need to see more of the concrete C# class code to spell out how to set up the complete query.

[edit] To fit in with the code you have now posted:

myDetectLines =
          (from myElements in config.Descendants("DetectLine")
           select new DetectLine()
           {
              DetectLineParam1 = (string)myElements.Element("ModuleParam1"),
              DetectLineParam2 = (string)myElements.Element("ModuleParam2"),
              ...

              Channels = (from channel in myElements.Element("Channels").Element("Channel")
                 select new Channel() {
                     ChannelParams = new ChannelParams() { ... = channel.Element("ChannelParams").Value }
                 }).ToList();
           }).ToList<DetectLine>();

Upvotes: 2

Related Questions