2014-03-01 17 views
2

比方說,我有以下XML:如何將由XmlProvider自動提供的選擇類型<...> .DomainTypes轉換爲F#中的枚舉?

<?xml version="1.0" encoding="UTF-16"?> 
<iAmConfused> 
    <helpMe feeling="anger" strength="100" mapping="1-1" /> 
    <helpMe feeling="frustration" strength="15" mapping="1-n" /> 
    <helpMe feeling="helplessness" strength="365" mapping="1-1" /> 
    <helpMe feeling="despair" strength="-1" mapping="1-n" /> 
</iAmConfused> 

並希望將其轉變成F#地圖:

open System.Xml 
open System.Xml.Linq 
open FSharp.Data 

type mappingType = 
    | oneToOneMapping = 00 
    | oneToManyMapping = 01 

type helpMe = { 
    strength : int; 
    mapping : mappingType} 

type iAmConfusedXmlType = XmlProvider<"""<?xml version="1.0" encoding="UTF-16"?><iAmConfused><helpMe feeling="anger" strength="100" mapping="1-1" /><helpMe feeling="frustration" strength="15" mapping="1-n" /><helpMe feeling="helplessness" strength="365" mapping="1-1" /><helpMe feeling="despair" strength="-1" mapping="1-n" /></iAmConfused>"""> 

let iAmConfusedXml = iAmConfusedXmlType.Parse("""<?xml version="1.0" encoding="UTF-16"?><iAmConfused><helpMe feeling="anger" strength="100" mapping="1-1" /><helpMe feeling="frustration" strength="15" mapping="1-n" /><helpMe feeling="helplessness" strength="365" mapping="1-1" /><helpMe feeling="despair" strength="-1" mapping="1-n" /></iAmConfused>""") 

let iWantThisMap = 
    iAmConfusedXml.GetHelpMes() 
    |> Seq.map (fun e -> e.Feeling, { 
     strength = e.Strength; 
     mapping = ???}) 
    |> Map.ofSeq 

XmlProvider正確地推斷出XML屬性mapping的類型是XmlProvider<...>.DomainTypes.MappingChoice。但是,我找不到將此類型轉換爲mappingType的方法。

首先,我試圖XML屬性mapping轉換成在隨後將它希望字符串枚舉mappingType,但即使這被證明是對我來說太困難了......

在上面的代碼重寫類型helpMe:

type helpMe = { 
    strength : int; 
    mapping : string} 

然後代???

string e.Strength 

給我"Some(1-1)""Some(1-n)"helpMe.mapping這不是我想要的。
如果我試圖取代???

string (defaultArg e.Mapping "") 

然後FSI理所當然地抱怨:

test.fs(165,38): error FS0001: This expression was expected to have type 
    'a option  
but here has type 
    XmlProvider<...>.DomainTypes.MappingChoice 

回答

2

好了,從字符串轉換爲mappingType,您可以定義一個小助手功能:

let convert m = 
    match m with 
    | "1-1" -> mappingType.oneToOneMapping 
    | _ -> mappingType.oneToManyMapping 

這將使您能夠編寫如下投影:

let iWantThisMap = 
    iAmConfusedXml.GetHelpMes() 
    |> Seq.map (fun e -> e.Feeling, { 
     strength = e.Strength; 
     mapping = (e.Mapping.Value |> convert) }) 
    |> Map.ofSeq 

現在,這裏有點作弊,因爲它只是叫e.Mapping.Value。如果e.MappingNone,這可能會引發異常,但由於e.Mapping始終有一個值,因此可以使用此處提供的數據。

相關問題