You were close. The GetXXX() methods return arrays, so you need to flatten the inner level. Instead of Seq.initInfinite
, which takes an generator function (int -> 'T)
, you could either use a combination of Seq.map
and Seq.concat
, or Seq.collect
to reduce the nesting by one level:
myXmlType.GetSample().GetLevel1s()
|> Seq.filter (fun L1 -> L1.Name = "level1Name2")
|> Seq.collect (fun L1 -> L1.GetLevel2s())
|> Seq.iter (fun L2 -> printfn "%A %A" L2.A L2.B)
which prints
50 500
376 1065
10 10
700 700
Edit So you're not interested in the attribute's sequence, but want the attributes of one specific instance as determined by its name? Then we have to search for the element, first in the outer level (may fail), than the inner (may fail too).
let myA, myB =
myXmlType.GetSample().GetLevel1s()
|> Seq.tryFind (fun L1 -> L1.Name = "level1Name2")
|> function
| None -> failwith "level1Name2 not found"
| Some L1 ->
L1.GetLevel2s()
|> Seq.tryFind (fun L2 -> L2.Name = "level2Name4")
|> function
| None -> failwith "level2Name4 not found"
| Some L2 -> L2.A, L2.B
// val myB : int = 1065
// val myA : int = 376
Edit2 You can combine the two approaches:
let myA, myB =
myXmlType.GetSample().GetLevel1s()
|> Seq.filter (fun L1 -> L1.Name = "level1Name2")
|> Seq.collect (fun L1 -> L1.GetLevel2s())
|> Seq.tryFind (fun L2 -> L2.Name = "level2Name4")
|> function
| None -> failwith "level2Name4 not found"
| Some L2 -> L2.A, L2.B