问题
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
→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 aValue : string
property.
来源:https://stackoverflow.com/questions/38337854/the-type-xmlprovider-parameter-does-not-support-the-operator-get-value