xml - 如何将 XmlProvider<...>.DomainTypes 自动提供的选择类型转换为 F# 中的枚举?

标签 xml f# enumeration type-providers f#-data

假设我有以下 XML:

<?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# map :

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

最佳答案

好吧,要将字符串转换为 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 始终有一个值.

关于xml - 如何将 XmlProvider<...>.DomainTypes 自动提供的选择类型转换为 F# 中的枚举?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22114677/

相关文章:

php - 如何从 xml 中隐藏一些 phing 目标

java - 使用 org.apache.commons.json.utils.XML toJson 将 XML 转换为 JSON - 将空元素更改为 "true"

enumeration - Elixir - 循环并添加到 map

ios - NSDirectoryEnumerator fileAttributes 为 nil

java - 解码 XML 数据中的 <br/>

c# - 如何在调用构造函数之前初始化 F# 中的字段?

f# - FRP 中的行为和事件有什么区别?

generics - F#:函数参数默认为类中的 obj

list - 在 Elixir 中有效压缩不等长列表

c# - XmlDocument 与 XmlWriter