score:2

Accepted answer

You can use Enumerable.Zip to merge parameter names sequence with parameter values sequence:

var reports = from r in xml.Root.Elements("Report")
              let parameters = r.Element("ParameterList")
              select new {
                  Name = (string)r.Attribute("Name"),
                  Parameters = parameters.Elements("Name")
                                         .Zip(parameters.Elements("Value"), 
                                              (n,v) => new { 
                                                  Name = (string)n, 
                                                  Value = (string)v 
                                              })
              };

That gives following reports collection:

[
  {
    "Name": "JobNotClose",
    "Parameters": [
      {
        "Name": "@StationCode",
        "Value": "LAX"
      },
      {
        "Name": "@ShipmentType",
        "Value": "SE|SI"
      }
    ]
  },
  {
    "Name": "JobWithoutSales",
    "Parameters": [
      {
        "Name": "@StationCode",
        "Value": "PA"
      },
      {
        "Name": "@JobDateFrom",
        "Value": "2013-10-1"
      },
      {
        "Name": "@JobDateTo",
        "Value": "2013-10-31"
      }
    ]
  }
]

score:0

Perhaps this will work.

You could take ParameterList elements as an IEnumerable using XNode.ElementsAfterSelf. Then loop through the result set and assume the elements are in pairs.

This will essentially give you a way to parse the elements in the order they appear in the ParameterList without worrying about .Descendants messing with the order.

Of course, the big assumption here is that the elements are always in pairs.

score:1

Try this (and by try I mean use):

var reports = xml.Descendants("Report").Select(reportElement => new
{
    Name = reportElement.Attribute("Name").Value,
    Parameters = reportElement.Descendants("ParameterList").Select(parameter => 
    {
        List<string> names = parameter.Elements("Name").Select(x=>x.Value).ToList();
        List<string> values = parameter.Elements("Value").Select(x=>x.Value).ToList();

        List<object>  pairs=new List<object>();

        for (int i = 0; i < names.Count; i++)
        {
            pairs.Add(new { Name = names[i], Value = values[i] });
        }

        return pairs;                    
    }).ToList()
}).ToList();

You can remove both ToList() calls. It just made it easier to test. Of course, there's the possibility that in your XML, the <Name> <Value> tags are not always complete (i.e. Name without Value). You can check that before doing the for loop.

EDIT: An alternative:

Dictionary<string, List<Tuple<string, string>>> rep = new Dictionary<string, List<Tuple<string, string>>>();

foreach (XElement report in xml.Elements("Report"))
{
    rep.Add(report.Attribute("Name").Value, new List<Tuple<string, string>>());

    List<string> names = report.Elements("ParameterList").FirstOrDefault().Elements("Name").Select(x => x.Value).ToList();
    List<string> values = report.Elements("ParameterList").FirstOrDefault().Elements("Value").Select(x => x.Value).ToList();

    for (int i = 0; i < names.Count; i++)
    {
         rep[report.Attribute("Name").Value].Add(new Tuple<string, string>(names[i], values[i]));
    }
}

Related Query

More Query from same tag