如何反序列化 XML 个子元素数量可变的元素?
How to deserialize XML elements with variable number of children?
XML 被反序列化的最小示例,我们称之为 newyorker.xml
:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Periodical subscription="true" issues_per_year="47">
<Title>The New Yorker</Title>
<Website>newyorker.com</Website>
<Edition available="true" date="2018-04-16">
<Contributor>Junot Diaz</Contributor>
<Contributor>Louisa Thomas</Contributor>
<Contributor>D. T. Max </Contributor>
<!-- More contributors omitted -->
</Edition>
<Edition available="true" date="...">
<Contributor>David Remnick</Contributor>
<Contributor>Malcolm Gladwell</Contributor>
<!-- More contributors omitted -->
</Edition>
<!-- More editions omitted -->
</Periodical>
<Other>
<Foo>Foo</Foo>
<Foo>Bar</Foo>
</Other>
</Root>
反序列化代码:
open System.Xml
open System.Xml.Serialization
let Deserialize<'T> file rootnode =
file |> File.ReadAllText
|> (fun data -> new StringReader(data))
|> (new System.Xml.Serialization.XmlSerializer(typeof<'T>, new System.Xml.Serialization.XmlRootAttribute(rootnode))).Deserialize
Edition
和 Periodical
类型的当前定义:
[<CLIMutable>]
type Edition = {
[<XmlAttribute("available")>] Available : bool
[<XmlAttribute("date")>] Date : string
[<XmlElement>] Contributor : string list // What goes here?
}
[<CLIMutable>]
type Periodical = {
[<XmlAttribute("subscription")>] Subscription : bool
[<XmlAttribute("issues_per_year")>] IssuesPerYear: int
[<XmlElement>] Title: string
[<XmlElement>] Website : string
[<XmlElement>] Edition : Edition list // What goes here?
}
我的目标是将文件反序列化到 Periodical
节点。这可能使用 XmlSerializer
吗?如果是这样,我应该如何调整 Periodical
和 Edition
的定义以使其工作?在 C# 中,appears 这可以通过声明 Periodical
包含一个 Edition
的数组(并且 Edition
包含一个 Contributor
的数组)来完成 -但我无法让它在 F# 中运行。
(我知道 XmlDocument
和 XDocument
。这个问题专门针对 XmlSerializer
。另外,修改 [=39= 的排列可能不可行] 文件由于遗留原因。)
[<CLIMutable>]
type Edition = {
...
[<XmlElement>] Contributor : string array
}
[<CLIMutable>]
type Periodical = {
...
[<XmlElement>] Edition : Edition array
}
let p = Deserialize<Periodical[]> "test.xml" "Root"
适合我
XML 被反序列化的最小示例,我们称之为 newyorker.xml
:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Periodical subscription="true" issues_per_year="47">
<Title>The New Yorker</Title>
<Website>newyorker.com</Website>
<Edition available="true" date="2018-04-16">
<Contributor>Junot Diaz</Contributor>
<Contributor>Louisa Thomas</Contributor>
<Contributor>D. T. Max </Contributor>
<!-- More contributors omitted -->
</Edition>
<Edition available="true" date="...">
<Contributor>David Remnick</Contributor>
<Contributor>Malcolm Gladwell</Contributor>
<!-- More contributors omitted -->
</Edition>
<!-- More editions omitted -->
</Periodical>
<Other>
<Foo>Foo</Foo>
<Foo>Bar</Foo>
</Other>
</Root>
反序列化代码:
open System.Xml
open System.Xml.Serialization
let Deserialize<'T> file rootnode =
file |> File.ReadAllText
|> (fun data -> new StringReader(data))
|> (new System.Xml.Serialization.XmlSerializer(typeof<'T>, new System.Xml.Serialization.XmlRootAttribute(rootnode))).Deserialize
Edition
和 Periodical
类型的当前定义:
[<CLIMutable>]
type Edition = {
[<XmlAttribute("available")>] Available : bool
[<XmlAttribute("date")>] Date : string
[<XmlElement>] Contributor : string list // What goes here?
}
[<CLIMutable>]
type Periodical = {
[<XmlAttribute("subscription")>] Subscription : bool
[<XmlAttribute("issues_per_year")>] IssuesPerYear: int
[<XmlElement>] Title: string
[<XmlElement>] Website : string
[<XmlElement>] Edition : Edition list // What goes here?
}
我的目标是将文件反序列化到 Periodical
节点。这可能使用 XmlSerializer
吗?如果是这样,我应该如何调整 Periodical
和 Edition
的定义以使其工作?在 C# 中,appears 这可以通过声明 Periodical
包含一个 Edition
的数组(并且 Edition
包含一个 Contributor
的数组)来完成 -但我无法让它在 F# 中运行。
(我知道 XmlDocument
和 XDocument
。这个问题专门针对 XmlSerializer
。另外,修改 [=39= 的排列可能不可行] 文件由于遗留原因。)
[<CLIMutable>]
type Edition = {
...
[<XmlElement>] Contributor : string array
}
[<CLIMutable>]
type Periodical = {
...
[<XmlElement>] Edition : Edition array
}
let p = Deserialize<Periodical[]> "test.xml" "Root"
适合我