我想编写一个从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
| _ -> ())
如何返回范围记录类型而不是单位?
答案 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类型提供程序的优点在于它不需要根据字符串值进行查找,因此您不太可能因拼写错误而导致错误。