【问题标题】:F# XML provider 'System.TypeInitializationException' when writingF# XML 提供程序'System.TypeInitializationException' 写入时
【发布时间】:2015-11-11 00:26:26
【问题描述】:

我在通过 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 是否仍然存在于那个 相对 路径中?
  • 谢谢,它似乎不喜欢相对路径,但是,它没有将记录保存到 XML。我的方法错了吗?

标签: xml f# f#-data


【解决方案1】:

从 cmets 来看,我认为您遇到的异常是因为您使用了相对路径。当您引用../TestProvider/Writers.xml 时,编译器将能够找到与您的代码相关的文件

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

FWIW,如果你内联示例,以下运行没有问题:

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,这个新值会立即被丢弃。

一种更有用的方法是首先获取生成的新数组:

> 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 值并将更新后的值写入文件。这不会自动发生。

【讨论】:

    猜你喜欢
    • 2014-05-25
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多