The type 'XmlProvider<…>.Parameter' does not support the operator 'get_Value'?

旧城冷巷雨未停 提交于 2019-12-12 01:49:26

问题


How to fix the code? Is the inline/Statically Resolved Type the same powerful as structural typing?

The type 'XmlProvider<...>.Parameter' does not support the operator 'get_Value'?

let input1 = """<r1><parameters><parameter name="token">1</parameter><parameter name="other">xxx</parameter></parameters><othersOf1>..sample....</othersOf1></r1>"""
let xml1 = XmlProvider<"""<r1><parameters><parameter name="token">1</parameter><parameter name="other">xxx</parameter></parameters><othersOf1>...</othersOf1></r1>""">.Parse(input1)

let inline get name parameters =
    parameters |> Seq.tryFind (fun x -> (^P : (member Name : 'a) x) = name)
    |> Option.map (fun v -> (^P : (member Value : 'b) v))

get "token" xml1.Parameters

回答1:


Value is only defined for nodes that have a single type (or types the type provider can unify, e.g. 2 and 3.0). In your example the second value is the string xxx, so a parameter gets two properties: Number and String, each returning an option of the respective type. You can either

  • change your input to have one single consistent value type (xxx &rightarrow; 2)

    let xml1 = XmlProvider<"""<r1><parameters><parameter name="token">1</parameter><parameter name="other">2</parameter></parameters><othersOf1>...</othersOf1></r1>""">.Parse(input1)
  • turn them into a single output type (e.g. string)

    let inline get name parameters =
        parameters |> Seq.tryFind (fun x -> (^P : (member Name : 'a) x) = name)
        |> Option.bind (fun v ->
            match (^P : (member Number : int option) v) with
            | Some number -> Some (string number)
            | None -> (^P : (member String : string option) v))
    
  • create an appropriate DU

    type Value = Number of int | Name of string
    
    let inline get name parameters =
        parameters |> Seq.tryFind (fun x -> (^P : (member Name : 'a) x) = name)
        |> Option.map (fun v ->
            match (^P : (member Number : int option) v) with
            | Some number -> Number number
            | None ->
                match (^P : (member String : string option) v) with
                | Some s -> Name s
                | _ -> failwith "Either number or string should be Some(value)")
    
  • if you don't know the values upfront, you can also tell the type provider to not infer them at all:

    XmlProvider<"""...""", InferTypesFromValues=false>
    

    this will cause parameters to have a Value : string property.



来源:https://stackoverflow.com/questions/38337854/the-type-xmlprovider-parameter-does-not-support-the-operator-get-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!