0

I have an object, built upon a XML schema and want to use LINQ to get the data out of it which I'm interested in :)

The structure look like the following example :

SimulationStep [1..n]
   - EnvironmentStep [1]
       - Events [0..n]
           - ResultingStateChanges [0..n]
               - Objects [1]
                   - Object[0..n]

each "Object" (the last one in that class chain) has an attribute x, y and z, meaning the position of this object in 3D space. Theres also an ID which is used to identify each object.

Now I want to collect all (x,y,z) triplets for each SimulationStep for the object which equals the given ID.

I tried it this way :

for (int i = 0; i < stepCount; i++)
{
    var events = from c in log.SimulationStep[i].EnvironmentSimulatorStep.EnvSimInputEvent
                        from d in c.ResultingStateChanges
                        from e in d.Agents.Agent
                       where e.id == id
                       select new { c.occurrenceTime, o = new Vector3((float)e.x, (float)e.y, (float)e.z) }
}

but all I get with this one, is the result (x,y,z) of SimulationStep 0. But I want a list with the positions in each step. This way : For example....

SimStep[0] - (0,0,0)
SimStep[1] - (5,0,0)
SimStep[2] - (10, 7, 0)
  • why not use XDocument it allows you to query XML data – Vincent Dagpin Apr 24 '13 at 09:09
  • @VincentDagpin: But i'm in LINQ now. –  Apr 24 '13 at 09:10
  • @Sandy There is a [Linq2XML](http://msdn.microsoft.com/en-us/library/bb387098.aspx) – Aron Apr 24 '13 at 09:10
  • @Aron: I'm not much exp in that. –  Apr 24 '13 at 09:11
  • Also from a very high level, without actually seeing your code it looks to be a [Access to Modified Closure](http://stackoverflow.com/questions/235455/access-to-modified-closure) issue. One needs to be EXTREMELY careful when mixing for loops with LinQ. – Aron Apr 24 '13 at 09:13

2 Answers2

1

Hope i got your ques.

Try this:

//Code

var events = from s in log.SimulationStep
                        from c in s.EnvironmentSimulatorStep.EnvSimInputEvent
                        from d in c.ResultingStateChanges
                        from e in d.Agents.Agent
                        where e.id == id
                        select new { 
                                     c.occurrenceTime, 
                                     o = new Vector3((float)e.x, 
                                     (float)e.y, 
                                     (float)e.z) 
                                    }
Kjartan
  • 18,591
  • 15
  • 71
  • 96
A Coder
  • 3,039
  • 7
  • 58
  • 129
  • 2
    Assuming that log.SimulationStep exposes IEnumerable then this would be the way I would go. – Aron Apr 24 '13 at 09:17
0

Without actually seeing the code I can't tell what type log.SimulationStep is. If it is indeed a Access Closure Modified issue, the way to fix this is simply to roll the for loop into our LinQ statement (or just use for loops all the way).

var events = from i in Enumerable.Range(0, stepCount)
             let simulationStep = log.SimulationStep[i]
             from c in simulationStep.EnvironmentSimulatorStep.EnvSimInputEvent
             from d in c.ResultingStateChanges
             from e in d.Agents.Agent
             where e.id == id
             select new { 
                          c.occurrenceTime, 
                          o = new Vector3((float)e.x, 
                          (float)e.y, 
                          (float)e.z) 
                        }
Kjartan
  • 18,591
  • 15
  • 71
  • 96
Aron
  • 15,464
  • 3
  • 31
  • 64