我正在编写一个读取xml文件并添加到列表的应用程序。代码如下:
open System.Net
open System.Collections.Generic
open System.Xml.Linq
open System
type IpRanges = {ipStart: IPAddress; ipEnd: IPAddress; subnet: IPAddress; mask: IPAddress}
type System.String with
member s1.isEqual(s2: string) =
System.String.Equals(s1, s2, System.StringComparison.CurrentCultureIgnoreCase)
let xname name = XName.Get name
let xattr (elem: XElement) (name:string) = elem.Attribute(xname name).Value
let loc (filename:string) (location:string) =
query {
for doc in XDocument.Load(filename).Descendants(xname "location") do
where ((xattr doc "name").isEqual(location))
select doc
}
let extractAddr (doc:seq<XElement>) =
let mutable startAddr:IPAddress = null
let mutable endAddr:IPAddress = null
let mutable subnet:IPAddress = null
let list:List<IpRanges> = new List<IpRanges>()
//let mutable mask = "0.0.0.0"
let parseIP (addr:string) = IPAddress.Parse addr
for e in doc do
match e.Name.LocalName with
| "start" -> startAddr <- parseIP e.Value
| "end" -> endAddr <- parseIP e.Value
| "subnet" -> subnet <- parseIP e.Value
| "mask" -> list.Add({ipStart = startAddr; ipEnd = endAddr; subnet = subnet; mask = parseIP(e.Value)}) |> ignore
| _ -> ()
// Return list
list
[<EntryPoint>]
let main argv =
let location = (loc ("C:\Temp\file.xml") "location").Descendants(xname "range").Descendants()
|> extractAddr
//let list = extractAddr location
Console.ReadLine() |> ignore
0 // return an integer exit code
执行我的代码后,列表
let list:List<IpRanges> = new List<IpRanges>()
我在函数extractAddr
中定义的为空为什么? 通过调试按预期工作,除了
| "mask" -> list.Add({ipStart = startAddr; ipEnd = endAddr; subnet = subnet; mask = parseIP(e.Value)}) |> ignore
不会添加到列表中。 Xml结构
<?xml version="1.0" encoding="UTF-8"?>
<ip>
<location name="test">
<range>
<start>192.20.10.1</start>
<end>192.20.10.255</end>
<subnet>255.255.255.0</subnet>
<gateway>192.20.16.1</gateway>
</range>sub
<range>
<start>192.20.12.1</start>
<end>192.20.12.255</end>
<subnet>255.255.255.0</subnet>
<gateway>192.20.16.1</gateway>
</range>
</location>
</ip>
答案 0 :(得分:2)
XML中没有“mask”元素,因此这种模式永远不会匹配。
另外,我会将extractAddr
函数更改为更像“XML结构证明”(如果没有名称为elmname
的元素,则不会抛出异常):
let parseRangeElement (range: XElement) elmname =
let e = range.Element(xname elmname)
if e <> null then
match IPAddress.TryParse(e.Value) with
| true, ip -> ip
| _ -> null
else null
let extractAddr (doc:seq<XElement>) =
doc
|> Seq.map (fun rngelm ->
{
ipStart = parseRangeElement rngelm "start"
ipEnd = parseRangeElement rngelm "end"
subnet = parseRangeElement rngelm "subnet"
mask = parseRangeElement rngelm "gateway"
})
|> List.ofSeq // if you really need list
[<EntryPoint>]
let main argv =
let location = (loc (xml) "test").Descendants(xname "range")
|> extractAddr
Console.ReadLine() |> ignore
0 // return an integer exit code