Multiple elements with the same name, with multiple children

c#, children, xml

Solution

You can define the following class representations:

public class api_data
{
    public string status { get; set; }

    [XmlElement]
    public session[] sessions { get; set; }
}

public class session
{
    public int id { get; set; }
    public string sessionID { get; set; }
    public int gameID { get; set; }
    public int maxPlayers { get; set; }
    public string hostIP { get; set; }
    public int hostPort { get; set; }
    public int inProgress { get; set; }
    public int timestamp { get; set; }
}

The key is the `[XmlElement]` tag on the `sessions` property, that will instruct the `XmlSerializer` to read/write XML using the schema sample you provided. To deserialize it, you can use the `XmlSerializer` as such:

//this might change, not sure how you obtain your xml, 
//but let's assume you already have it available as a string
byte[] xmlBytes = System.Text.Encoding.UTF8.GetBytes(xmlData); 

var stream = new MemoryStream(xmlBytes);
XmlSerializer serializer = new XmlSerializer(typeof(api_data));
api_data apidata = (api_data)serializer.Deserialize(stream);

Don't need any more XML adornment or setup than that to read it in (tested and working).

EDIT: Though you may want to consider using some other XML attributes to transfer to some nicer naming conventions, and we can also `List<Session>` to boot instead of an array:

[XmlRoot("api_data")]
public class ApiData
{
    [XmlElement("status")]
    public string Status { get; set; }

    [XmlElement("sessions")]
    public List<Session> Sessions { get; set; }
}

public class Session
{
    [XmlElement("id")]
    public int ID { get; set; }

    [XmlElement("sessionID")]
    public string SessionID { get; set; }

    [XmlElement("gameID")]
    public int GameID { get; set; }

    [XmlElement("maxPlayers")]
    public int MaxPlayers { get; set; }

    [XmlElement("hostIP")]
    public string HostIP { get; set; }

    [XmlElement("hostPort")]
    public int HostPort { get; set; }

    [XmlElement("inProgress")]
    public int InProgress { get; set; }

    [XmlElement("timestamp")]
    public int TimeStamp { get; set; }
}

EDIT: Just noticed that you need to turn this into a multidimensional array (not sure why, but you specify that's legacy). Well at this point, you have a nice object model from which you can do this data transfer. Not sure how you do the typing, but let's just assuming `object` type array for now:

ApiData apiData = DeserializeMyApiData(); // from above
array[0][0] = apiData.Status;
for(int i = 1; i <= apiData.Sessions.Count; i++)
{
    var session = apiData.Sessions[i - 1];
    array[i] = new object[8];
    array[i][0] = session.ID;
    array[i][1] = session.SessionID;
    array[i][2] = session.GameID;
    array[i][3] = session.MaxPlayers;
    array[i][4] = session.HostIP;
    array[i][5] = session.HostPort;
    array[i][6] = session.InProgress;
    array[i][7] = session.TimeStamp;
}

That will go through and build up your array regardless of how many sessions you have.

Problem

I have come across a problem, I need to basicly deserialize this: ``` <?xml version="1.0" encoding="UTF-8"?> <api_data> <status>ok</status> <sessions> <id>2</id> <sessionID>6bfd1f1a7e87a8a6ed476234ad1d6e86</sessionID> <gameID>1</gameID> <maxPlayers>8</maxPlayers> <hostIP>12.0.0.1</hostIP> <hostPort>1993</hostPort> <inProgress>0</inProgress> <timestamp>1358894690</timestamp> </sessions> <sessions> <id>3</id> <sessionID>eeb4dc2df32f885c2b7d13f28a246830</sessionID> <gameID>1</gameID> <maxPlayers>8</maxPlayers> <hostIP>12.0.0.1</hostIP> <hostPort>1993</hostPort> <inProgress>0</inProgress> <timestamp>1358894732</timestamp> </sessions> </api_data> ``` And I need to convert that to usable data, its also dynamic, so there could be more than just 2 session elements, there could be 4, 20, or 0, the code I have now is just broken, and I was wondering whats a good method to get this to work? Currently I am up to the point of the XDocument class, with all this loaded. And I need to return a multi-dimensional array with this data. EDIT: Current code, completely broken: ``` var xmlSessions = xmlDATA.Descendants("api_data").Elements("sessions").Select(x => x); result = new string[xmlDATA.Descendants("api_data").Count(), 7]; ``` EDIT 2: More info The way I was thinking the MultiDimensional Array would be is as follows: ``` array[0,0] "ok" //Status array[1,0 to 7] //First Session details go here array[2,0 to 7] //Second session details go here, and so forth. ```

Original source