如何在匹配模式中创建记录

时间:2015-02-16 09:17:56

标签: f#

我想编写一个从xml文件读取ip地址的应用程序。该文件看起来像

<range>
    <start>192.168.40.1</start>
    <end>192.168.50.255</end>
    <subnet>255.255.255.0</subnet>
    <gateway>192.168.50.1</gateway>
</range>

我创建一个记录类型来保存IP地址

type Scope = { Start: IPAddress; End: IPAddress; Subnetmask: IPAddress; Gateway: IPAddress } 

我写了一个单位函数,输出ip的。

loc
            |> Seq.iter (fun e -> match e.Name.LocalName with
                                    |"start" -> printfn "Start %s" e.Value
                                    |"end" -> printfn "End %s" e.Value
                                    |"subnet" -> printfn "Subnet %s" e.Value
                                    |"gateway" -> printfn "Gateway %s" e.Value
                                    | _ -> ())

如何返回范围记录类型而不是单位?

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,XML type provider使这更容易。您只需将其指向一个示例文件,它就会推断出结构并让您轻松阅读该文件:

type RangeFile = XmlProvider<"sample.xml">
let range = RangeFile.Load("file-you-want-to-read.xml")

let scope = 
  { Start = IPAddress.Parse(range.Start)
    End = IPAddress.Parse(range.End)
    Subnetmask = IPAddress.Parse(range.Subnet)
    Gateway = IPAddress.Parse(range.Gateway) }

那就是说,你当然也可以自己实现。您编写的代码是一个良好的开端 - 有很多方法可以做到这一点,但无论如何,您需要根据元素的本地名称进行一些查找(以查找开始,结束等)

一种选择是将所有属性加载到字典中:

let lookup = 
   loc
   |> Seq.map (fun e -> e.Name.LocalName, IPAddress.Parse(e.Value)
   |> dict

现在,您有一个查找表,其中包含每个键的IPAddress,因此您只需使用以下内容创建Scope值:

let scope = 
  { Start = lookup.["start"]; End = lookup.["end"];
    Subnetmask = lookup.["subnet"]; Gateway = lookup.["gateway"] }

也就是说,XML类型提供程序的优点在于它不需要根据字符串值进行查找,因此您不太可能因拼写错误而导致错误。