How to get two-in-depth XML attributes using the F # Data XML Type Provider?

I want to get the attributes aand blet say ( level2 name=) level2Name4in ( level1 name=) level1Name2using the F # Data XML Type Provider from the following XML:

<?xml version="1.0" encoding="UTF-16"?>
<ROOT>
    <level1 name="level1Name1">
        <level2 name="level2Name1" a="8" b="104" />
        <level2 name="level2Name2" a="85" b="140" />
    </level1>
    <level1 name="level1Name2">
        <level2 name="level2Name3" a="50" b="500" />
        <level2 name="level2Name4" a="376" b="1065" />
        <level2 name="level2Name5" a="10" b="10" />
        <level2 name="level2Name6" a="700" b="700" />
    </level1>
    <level1 name="level1Name3">
        <level2 name="level2Name7" a="502" b="66" />
    </level1>
</ROOT>

However, I cannot convert / deploy level2to a map and not get the necessary information from there:

open System.Xml.Linq
open FSharp.Data

type myXmlType = XmlProvider<"""<?xml version="1.0" encoding="UTF-16"?><ROOT><level1 name="level1Name1"><level2 name="level2Name1" a="8" b="104" /><level2 name="level2Name2" a="85" b="140" /></level1><level1 name="level1Name2"><level2 name="level2Name3" a="50" b="500" /><level2 name="level2Name4" a="376" b="1065" /><level2 name="level2Name5" a="10" b="10" /><level2 name="level2Name6" a="700" b="700" /></level1><level1 name="level1Name3"><level2 name="level2Name7" a="502" b="66" /></level1></ROOT>""">

let myXml = myXmlType.Parse("""<?xml version="1.0" encoding="UTF-16"?><ROOT><level1 name="level1Name1"><level2 name="level2Name1" a="8" b="104" /><level2 name="level2Name2" a="85" b="140" /></level1><level1 name="level1Name2"><level2 name="level2Name3" a="50" b="500" /><level2 name="level2Name4" a="376" b="1065" /><level2 name="level2Name5" a="10" b="10" /><level2 name="level2Name6" a="700" b="700" /></level1><level1 name="level1Name3"><level2 name="level2Name7" a="502" b="66" /></level1></ROOT>""")

let myA, myB =
    myXml.GetLevel1s()
    |> Seq.filter (fun L1 -> L1.Name = "level1Name2")
    |> Seq.initInfinite (fun i L1 -> L1.GetLevel2s())
    ...

This is where I am stuck. How to expand / expand / transform level2here? And then how to get aand b( level2 name=) level2Name4in ( level1 name=) level1Name2?

+3
source share
1 answer

. GetXXX() , . Seq.initInfinite, (int -> 'T), Seq.map Seq.concat Seq.collect, :

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)

50 500
376 1065
10 10
700 700

. , , , ? , ( ), ( ).

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. :

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
+4

All Articles