2016-07-12 7 views
0

Wie man den Code repariert? Ist der Inline/Statisch aufgelöste Typ derselbe wie der Strukturtyp?Der Typ 'XmlProvider <...> .Parameter' unterstützt den Operator 'get_Value' nicht?

Der Typ 'XmlProvider < ...>. Parameter' unterstützt den Operator 'get_Value' nicht?

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 

Antwort

6

Value ist nur für den Knoten definiert, der (die Typ-Provider kann vereinen, beispielsweise 2 und 3,0 oder Typen) einen einzigen Typ aufweisen. In Ihrem Beispiel ist der zweite Wert der String xxx, so dass ein Parameter zwei Eigenschaften erhält: Number und String, die jeweils einen option des jeweiligen Typs zurückgeben. Sie können entweder

  • ändern Sie Ihre Eingabe einen einzigen konsistenten Werttyp (xxx & rightarrow; 2) haben

     
    let xml1 = XmlProvider<"""<r1><parameters><parameter name="token">1</parameter><parameter name="other">2</parameter></parameters><othersOf1>...</othersOf1></r1>""">.Parse(input1)
  • machen sie zu einem einzigen Ausgangstyp (zB 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)) 
    
  • erstellen Sie eine geeignete 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)") 
    
  • wenn Sie die Werte nicht wissen im Voraus, können Sie auch den Typ mitteilen zu nicht sie folgern überhaupt:

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

    dies parameters verursachen eine Value : string Eigenschaft haben .

+0

Danke, das funktioniert, wenn der Token '1' ist. Es schlägt jedoch fehl, wenn ich es nach Änderung von "1" auf "a1" teste. Die reale Eingabe kann ein Text sein, der nicht in eine Zahl umgewandelt werden kann. – ca9163d9

+1

Ja, dann hast du wieder 'Value', weil alle Werte nur' string's sind. Sie benötigen ein * repräsentatives * Beispiel Ihrer Eingabe, um einen geeigneten Typ generieren zu lassen. – CaringDev

+0

@ dc7a9163d9 siehe zuletzt hinzugefügte Option – CaringDev