为什么得到空列表
Why got empty list
我正在编写一个读取 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>
XML 中没有 "mask" 元素,因此此模式永远不会匹配。
此外,我会将您的 extractAddr
函数更改为更像这样的 "XML structure proof"(如果没有名称为 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
我正在编写一个读取 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>
XML 中没有 "mask" 元素,因此此模式永远不会匹配。
此外,我会将您的 extractAddr
函数更改为更像这样的 "XML structure proof"(如果没有名称为 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