F# XML provider 'System.TypeInitializationException' 编写时
F# XML provider 'System.TypeInitializationException' when writing
我在 F# 数据中通过 XML 类型提供程序写入时遇到一些问题。
这是我正在加载的文件:
<authors>
<science>
<author name="Paul Feyerabend" born="1924" />
<author name="Thomas Kuhn" />
</science>
<mathematics>
<author name="Bertrand Russell" />
<author name="Ludwig Wittgenstein" born="1889" />
<author name="Alfred North Whitehead" died="1947" />
</mathematics>
</authors>
我已将作者分成子类别,这样每次我想添加作者时都不必重写整个文件(这是正确的还是我遗漏了什么?)
这是代码:
open FSharp.Data
open System.IO
type Writers = XmlProvider<"../TestProvider/Writers.xml">
let writers = Writers.Load(File.OpenText("../TestProvider/Writers.xml"))
[<EntryPoint>]
let main argv =
printfn "%A" argv
Array.append writers.Science.Authors [| Writers.Author("Richard Feynman", Some 1918) |] |> ignore
0 // return an integer exit code
这给我带来了以下错误:
System.TypeInitializationException was unhandled
Message: An unhandled exception of type 'System.TypeInitializationException' occurred in TestProvider.exe
Additional information: The type initializer for '<StartupCode$TestProvider>.$Program' threw an exception.
根据评论,我认为您遇到的异常是因为您使用了相对路径。当您引用 ../TestProvider/Writers.xml
时,编译器将能够找到与您的代码相关的文件 .
假设您使用 Visual Studio,当它编译代码时,它会将二进制文件放入 bin/Debug
或 bin/Release
。当您尝试 运行 这些文件夹之一的可执行文件时,它会期望文件位于 bin/TestProvider/Writers.xml
中,这很可能不存在。这很可能发生在您调用 File.OpenText
时(您没有 post 完整的异常,但我希望在 InnerException 的某个地方,您会收到一条消息)。
FWIW,如果您内联示例,则以下 运行s 没有问题:
open FSharp.Data
type Writers = XmlProvider<"""<authors>
<science>
<author name="Paul Feyerabend" born="1924" />
<author name="Thomas Kuhn" />
</science>
<mathematics>
<author name="Bertrand Russell" />
<author name="Ludwig Wittgenstein" born="1889" />
<author name="Alfred North Whitehead" died="1947" />
</mathematics>
</authors>""">
let writers = Writers.GetSample()
Array.append writers.Science.Authors [| Writers.Author("Richard Feynman", Some 1918) |] |> ignore
不过,这不会对文件进行任何更改。
writers.Science.Authors
是一个数组(在内存中),[| Writers.Author("Richard Feynman", Some 1918) |]
是另一个数组。当您调用 Array.append
时,它 returns 一个新的 数组附加了两个数组,但是由于使用了 ignore
,这个新值是立即扔掉。
一种稍微有用的方法是首先获取生成的新数组:
> let updatedScientists =
writers.Science.Authors
|> Array.append [| Writers.Author("Richard Feynman", Some 1918) |];;
val updatedScientists : XmlProvider<...>.Author [] =
[|<author name="Richard Feynman" born="1918" />;
<author name="Paul Feyerabend" born="1924" />;
<author name="Thomas Kuhn" />|]
如您所知,这只会为您提供新的 Author
数组。
您仍然需要将其添加回 writers
值并将更新后的值写入文件。这不会自动发生。
我在 F# 数据中通过 XML 类型提供程序写入时遇到一些问题。
这是我正在加载的文件:
<authors>
<science>
<author name="Paul Feyerabend" born="1924" />
<author name="Thomas Kuhn" />
</science>
<mathematics>
<author name="Bertrand Russell" />
<author name="Ludwig Wittgenstein" born="1889" />
<author name="Alfred North Whitehead" died="1947" />
</mathematics>
</authors>
我已将作者分成子类别,这样每次我想添加作者时都不必重写整个文件(这是正确的还是我遗漏了什么?)
这是代码:
open FSharp.Data
open System.IO
type Writers = XmlProvider<"../TestProvider/Writers.xml">
let writers = Writers.Load(File.OpenText("../TestProvider/Writers.xml"))
[<EntryPoint>]
let main argv =
printfn "%A" argv
Array.append writers.Science.Authors [| Writers.Author("Richard Feynman", Some 1918) |] |> ignore
0 // return an integer exit code
这给我带来了以下错误:
System.TypeInitializationException was unhandled
Message: An unhandled exception of type 'System.TypeInitializationException' occurred in TestProvider.exe
Additional information: The type initializer for '<StartupCode$TestProvider>.$Program' threw an exception.
根据评论,我认为您遇到的异常是因为您使用了相对路径。当您引用 ../TestProvider/Writers.xml
时,编译器将能够找到与您的代码相关的文件 .
假设您使用 Visual Studio,当它编译代码时,它会将二进制文件放入 bin/Debug
或 bin/Release
。当您尝试 运行 这些文件夹之一的可执行文件时,它会期望文件位于 bin/TestProvider/Writers.xml
中,这很可能不存在。这很可能发生在您调用 File.OpenText
时(您没有 post 完整的异常,但我希望在 InnerException 的某个地方,您会收到一条消息)。
FWIW,如果您内联示例,则以下 运行s 没有问题:
open FSharp.Data
type Writers = XmlProvider<"""<authors>
<science>
<author name="Paul Feyerabend" born="1924" />
<author name="Thomas Kuhn" />
</science>
<mathematics>
<author name="Bertrand Russell" />
<author name="Ludwig Wittgenstein" born="1889" />
<author name="Alfred North Whitehead" died="1947" />
</mathematics>
</authors>""">
let writers = Writers.GetSample()
Array.append writers.Science.Authors [| Writers.Author("Richard Feynman", Some 1918) |] |> ignore
不过,这不会对文件进行任何更改。
writers.Science.Authors
是一个数组(在内存中),[| Writers.Author("Richard Feynman", Some 1918) |]
是另一个数组。当您调用 Array.append
时,它 returns 一个新的 数组附加了两个数组,但是由于使用了 ignore
,这个新值是立即扔掉。
一种稍微有用的方法是首先获取生成的新数组:
> let updatedScientists =
writers.Science.Authors
|> Array.append [| Writers.Author("Richard Feynman", Some 1918) |];;
val updatedScientists : XmlProvider<...>.Author [] =
[|<author name="Richard Feynman" born="1918" />;
<author name="Paul Feyerabend" born="1924" />;
<author name="Thomas Kuhn" />|]
如您所知,这只会为您提供新的 Author
数组。
您仍然需要将其添加回 writers
值并将更新后的值写入文件。这不会自动发生。