Search code examples
xmlf#type-providersf#-data

How to reference the first node from the xml type provider


I cannot seem to be able to select only the first addresses postcode from the xml type provider.

The fragment below is a fragment from larger XML document:

                <applicant>
                    <address>
                        <buildingno>8</buildingno>
                        <street1>Bob Way</street1>
                        <locality>Jones</locality>
                        <posttown>Somewhere</posttown>
                        <postcode>AB12 3QE</postcode>
                    </address>
                    <address>
                        <buildingno>9</buildingno>
                        <street1>SomeStreet</street1>
                        <posttown>Somewhere</posttown>
                        <postcode>AB13 4FE</postcode>
                    </address>
                </applicant>

I have loaded the documents in the type provider:

type XmlReqSample = XmlProvider<"C:\\Temp\\requests\\samples.xml", SampleIsList=true, Global=true>

Some of the requests only have one address, some have two or more which is why I tried loading a sample. I want to know how to select only the first addresses postcode:

// 'file' is a string of XML data
let doc = XmlReqSample.Parse(file)
let postCode = doc.Body.Applicant.Address.Value.Postcode.Value

However, I cannot select only the first postcode.

How do I select the first address and in particular the postcode?


Solution

  • #r "packages/FSharp.Data.2.2.3/lib/portable-net40+sl5+wp8+win8/FSharp.Data.dll"
    #r "System.Xml.Linq"
    
    open FSharp.Data
    
    type XmlReqSample = XmlProvider<"sample.xml">
    // file is a string of XML data
    let applicant = XmlReqSample.Load(file)
    
    let firstAddress =
      applicant.Addresses
       |> Array.tryFind (fun _ -> true)
    

    val firstAddess : Address option

    Furthermore to get a postcode from an Address you can define a little function:

    let getPostCode address =
      address |> Option.bind (fun (t:XmlReqSample.Address) -> Some t.Postcode)  
    

    and use like:

    getPostCode firstAddress
    

    val it : string option = Some "AB12 3QE"