首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编写F# XML提供程序“System.TypeInitializationException”

编写F# XML提供程序“System.TypeInitializationException”
EN

Stack Overflow用户
提问于 2015-11-10 12:44:57
回答 1查看 283关注 0票数 1

我在编写F#数据中的XML类型提供程序时遇到了一些问题。

这是我要加载的文件:

代码语言:javascript
复制
<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>

我已经将作者分成了几个子类别,所以每次我想要添加一个作者时,我都不需要重写整个文件(这是正确的,还是我遗漏了什么?)

这是密码:

代码语言:javascript
复制
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

这使我犯了以下错误:

代码语言:javascript
复制
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.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-10 16:26:26

从评论中,我认为你得到的例外是因为你使用了一个相对路径。当您引用../TestProvider/Writers.xml时,编译器将能够找到相对于您的代码的文件。

假设您使用Visual,在编译代码时,它会将二进制文件放在bin/Debugbin/Release中。当您尝试从其中一个文件夹运行可执行文件时,它将期望文件位于bin/TestProvider/Writers.xml中,这很可能是不存在的。这种情况最有可能发生在您调用File.OpenText时(您没有发布完整的异常,但我希望在InnerException中的某个地方会有这样的消息)。

FWIW,如果您内联该示例,则以下操作没有问题:

代码语言:javascript
复制
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时,它将返回一个新数组,并附加两个数组,但是由于使用了ignore,这个新值将被立即丢弃。

一种稍微有用的方法是首先获得产生的新数组:

代码语言:javascript
复制
> 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值,并将更新的值写入文件。这不是自动发生的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33630308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档