无法反序列化 XML 字符串
Unable to deserialize an XML string
我有以下 xml ,我试图按如下方式反序列化,但出现错误:
There was an error reflecting type 'System.Collections.Generic.List`1[MyApp.Models.Field]
下面是我的代码
public class FieldList
{
[XmlArray("fields")]
[XmlArrayItem("field")]
List<Field> Fields { get; set; }
}
public class Field
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("required")]
public bool Required { get; set; }
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
[XmlElement("option")]
[JsonProperty("values")]
public List<Option> Options { get; set; }
}
public class Option
{
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
[XmlAttribute("selected")]
public bool Selected { get; set; }
/// <remarks/>
[XmlIgnore()]
public bool SelectedSpecified { get; set; }
[XmlText]
public string Text { get; set; }
}
var xml = @"<?xml version=""1.0"" ?>
<form-template>
<fields>
<field type=""select"" required=""true"" label=""Cars"" name=""cars"" >
<option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option>
<option label=""Nisan"" value=""Nisan"" >Nisan</option>
</field>
</fields>
</form-template>";
var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template"));
var stringReader = new StringReader(xml);
var xmlFields = (FieldList)serializer.Deserialize(stringReader);
我做错了什么?
* 更新 *
根据下面的评论更改
public IEnumerable<Option> Options { get; set; }
到
public List<Option> Options { get; set; }
修复了错误,但现在没有反序列化 - 变量 xmlFields
为空???我需要从特定节点读取还是应该无关紧要?
XmlSerializer 无法序列化抽象属性,因此请将 IEnumerable 更改为 List,如下所示,
public IEnumerable<Option> Options { get; set; }
到
public List<Option> Options { get; set; }
您的根元素与您拥有的 XML 结构不匹配。我编辑了 XML 如下,
var xml = "<?xml version=\"1.0\" ?>" +
" " +
" <Fields>" +
" <Field Type=\"select\" Required=\"true\" Label=\"Cars\" Name=\"cars\" >" +
" <option label=\"Toyota\" lalue=\"Toyota\" selected=\"true\">Toyota</option>" +
" <option label=\"Nisan\" value=\"Nisan\" >Nisan</option>" +
" </Field>" +
" </Fields>";
并将代码反序列化为,
XmlSerializer serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("Fields"));
var stringReader = new StringReader(xml);
List<Field> xmlFields = (List<Field>)serializer.Deserialize(stringReader);
现在可以反序列化了。请查看输出,
您需要正确生成要将 xml 序列化到的 类。将正确的 XML 不带双 "double quotes" 复制到剪贴板,转到 Visual Studio 中解决方案中的任何 cs 文件。单击 编辑->选择性粘贴-> 将 XML 粘贴为 类。这将在您的 cs 文件中正确生成 类 以进行转换。然后,将这些更改为自动实现的属性,而不是使用私有变量以减少屏幕上的混乱。
用下面类的集合,反序列化为
XmlSerializer serializer = new XmlSerializer(typeof(FormTemplate));
var xml = @"<?xml version=""1.0"" ?>
<form-template>
<fields>
<field type=""select"" required=""true"" label=""Cars"" name=""cars"" >
<option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option>
<option label=""Nisan"" value=""Nisan"" >Nisan</option>
</field>
</fields>
</form-template>";
var stringReader = new StringReader(xml);
var xmlFields = serializer.Deserialize(stringReader);
自动生成的一组类修改为
将属性更改为自动实现的属性。
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute("form-template", Namespace = "", IsNullable = false)]
public partial class FormTemplate
{
/// <remarks/>
public Fields fields { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class Fields
{
/// <remarks/>
public SingleField field { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SingleField
{
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("option")]
public Option[] option { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public bool required { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string label { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class Option
{
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string label { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string value { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public bool selected { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool selectedSpecified { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value { get; set; }
}
让我们看看你的代码。
new XmlRootAttribute("form-template")
映射到 <form-template>
节点。
public class Field
映射到 <field
节点。
但没有映射到 <fields>
节点。
添加以下内容class:
public class FieldList
{
[XmlArray("fields")]
[XmlArrayItem("field")]
public List<Field> Fields { get; set; }
}
它应该有效:
var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template"));
var stringReader = new StringReader(xml);
var xmlFields = (FieldList)serializer.Deserialize(stringReader);
此外,您应该在 Option
class 中添加一个 属性:
[XmlText]
public string Text { get; set; }
更新。
你可以去掉FieldList
class。但是你必须手动跳过部分 xml 个节点。
List<Field> xmlFields;
var serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("fields"));
// You can read from a stream or from a StringReader instead of a file
using (var xmlReader = XmlReader.Create("test.xml"))
{
// Skip <form-template> node
xmlReader.ReadToFollowing("fields");
xmlFields = (List<Field>)serializer.Deserialize(xmlReader);
}
将 XmlType
属性添加到您的 class:
[XmlType("field")]
public class Field
我有以下 xml ,我试图按如下方式反序列化,但出现错误:
There was an error reflecting type 'System.Collections.Generic.List`1[MyApp.Models.Field]
下面是我的代码
public class FieldList
{
[XmlArray("fields")]
[XmlArrayItem("field")]
List<Field> Fields { get; set; }
}
public class Field
{
[XmlAttribute("type")]
public string Type { get; set; }
[XmlAttribute("required")]
public bool Required { get; set; }
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
[XmlElement("option")]
[JsonProperty("values")]
public List<Option> Options { get; set; }
}
public class Option
{
[XmlAttribute("label")]
public string Label { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
[XmlAttribute("selected")]
public bool Selected { get; set; }
/// <remarks/>
[XmlIgnore()]
public bool SelectedSpecified { get; set; }
[XmlText]
public string Text { get; set; }
}
var xml = @"<?xml version=""1.0"" ?>
<form-template>
<fields>
<field type=""select"" required=""true"" label=""Cars"" name=""cars"" >
<option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option>
<option label=""Nisan"" value=""Nisan"" >Nisan</option>
</field>
</fields>
</form-template>";
var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template"));
var stringReader = new StringReader(xml);
var xmlFields = (FieldList)serializer.Deserialize(stringReader);
我做错了什么?
* 更新 *
根据下面的评论更改
public IEnumerable<Option> Options { get; set; }
到
public List<Option> Options { get; set; }
修复了错误,但现在没有反序列化 - 变量 xmlFields
为空???我需要从特定节点读取还是应该无关紧要?
XmlSerializer 无法序列化抽象属性,因此请将 IEnumerable 更改为 List,如下所示,
public IEnumerable<Option> Options { get; set; }
到
public List<Option> Options { get; set; }
您的根元素与您拥有的 XML 结构不匹配。我编辑了 XML 如下,
var xml = "<?xml version=\"1.0\" ?>" +
" " +
" <Fields>" +
" <Field Type=\"select\" Required=\"true\" Label=\"Cars\" Name=\"cars\" >" +
" <option label=\"Toyota\" lalue=\"Toyota\" selected=\"true\">Toyota</option>" +
" <option label=\"Nisan\" value=\"Nisan\" >Nisan</option>" +
" </Field>" +
" </Fields>";
并将代码反序列化为,
XmlSerializer serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("Fields"));
var stringReader = new StringReader(xml);
List<Field> xmlFields = (List<Field>)serializer.Deserialize(stringReader);
现在可以反序列化了。请查看输出,
您需要正确生成要将 xml 序列化到的 类。将正确的 XML 不带双 "double quotes" 复制到剪贴板,转到 Visual Studio 中解决方案中的任何 cs 文件。单击 编辑->选择性粘贴-> 将 XML 粘贴为 类。这将在您的 cs 文件中正确生成 类 以进行转换。然后,将这些更改为自动实现的属性,而不是使用私有变量以减少屏幕上的混乱。
用下面类的集合,反序列化为
XmlSerializer serializer = new XmlSerializer(typeof(FormTemplate));
var xml = @"<?xml version=""1.0"" ?>
<form-template>
<fields>
<field type=""select"" required=""true"" label=""Cars"" name=""cars"" >
<option label=""Toyota"" value=""Toyota"" selected=""true"">Toyota</option>
<option label=""Nisan"" value=""Nisan"" >Nisan</option>
</field>
</fields>
</form-template>";
var stringReader = new StringReader(xml);
var xmlFields = serializer.Deserialize(stringReader);
自动生成的一组类修改为 将属性更改为自动实现的属性。
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute("form-template", Namespace = "", IsNullable = false)]
public partial class FormTemplate
{
/// <remarks/>
public Fields fields { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class Fields
{
/// <remarks/>
public SingleField field { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class SingleField
{
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("option")]
public Option[] option { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public bool required { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string label { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name { get; set; }
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class Option
{
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string label { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string value { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public bool selected { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool selectedSpecified { get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string Value { get; set; }
}
让我们看看你的代码。
new XmlRootAttribute("form-template")
映射到 <form-template>
节点。
public class Field
映射到 <field
节点。
但没有映射到 <fields>
节点。
添加以下内容class:
public class FieldList
{
[XmlArray("fields")]
[XmlArrayItem("field")]
public List<Field> Fields { get; set; }
}
它应该有效:
var serializer = new XmlSerializer(typeof(FieldList), new XmlRootAttribute("form-template"));
var stringReader = new StringReader(xml);
var xmlFields = (FieldList)serializer.Deserialize(stringReader);
此外,您应该在 Option
class 中添加一个 属性:
[XmlText]
public string Text { get; set; }
更新。
你可以去掉FieldList
class。但是你必须手动跳过部分 xml 个节点。
List<Field> xmlFields;
var serializer = new XmlSerializer(typeof(List<Field>), new XmlRootAttribute("fields"));
// You can read from a stream or from a StringReader instead of a file
using (var xmlReader = XmlReader.Create("test.xml"))
{
// Skip <form-template> node
xmlReader.ReadToFollowing("fields");
xmlFields = (List<Field>)serializer.Deserialize(xmlReader);
}
将 XmlType
属性添加到您的 class:
[XmlType("field")]
public class Field