如何反序列化此XML文档:
1020 Nissan Sentra 1010 Toyota Corolla 1111 Honda Accord
我有这个:
[Serializable()] public class Car { [System.Xml.Serialization.XmlElementAttribute("StockNumber")] public string StockNumber{ get; set; } [System.Xml.Serialization.XmlElementAttribute("Make")] public string Make{ get; set; } [System.Xml.Serialization.XmlElementAttribute("Model")] public string Model{ get; set; } }
.
[System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)] public class Cars { [XmlArrayItem(typeof(Car))] public Car[] Car { get; set; } }
.
public class CarSerializer { public Cars Deserialize() { Cars[] cars = null; string path = HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data/") + "cars.xml"; XmlSerializer serializer = new XmlSerializer(typeof(Cars[])); StreamReader reader = new StreamReader(path); reader.ReadToEnd(); cars = (Cars[])serializer.Deserialize(reader); reader.Close(); return cars; } }
似乎不起作用:-(
你如何将xml保存到文件中,并使用xsd生成C#类?
将文件写入磁盘(我将其命名为foo.xml)
生成xsd: xsd foo.xml
生成C#: xsd foo.xsd /classes
Et voila - 和C#代码文件应该能够通过XmlSerializer
以下方式读取数据:
XmlSerializer ser = new XmlSerializer(typeof(Cars)); Cars cars; using (XmlReader reader = XmlReader.Create(path)) { cars = (Cars) ser.Deserialize(reader); }
(包括项目中生成的foo.cs)
这是一个工作版本.我将XmlElementAttribute标签更改为XmlElement,因为在xml中,StockNumber,Make和Model值是元素,而不是属性.我也删除了reader.ReadToEnd(); (该函数读取整个流并返回一个字符串,因此Deserialze()函数不再使用读取器......位置位于流的末尾).我也给命名:)带来了一些自由.
以下是课程:
[Serializable()] public class Car { [System.Xml.Serialization.XmlElement("StockNumber")] public string StockNumber { get; set; } [System.Xml.Serialization.XmlElement("Make")] public string Make { get; set; } [System.Xml.Serialization.XmlElement("Model")] public string Model { get; set; } } [Serializable()] [System.Xml.Serialization.XmlRoot("CarCollection")] public class CarCollection { [XmlArray("Cars")] [XmlArrayItem("Car", typeof(Car))] public Car[] Car { get; set; } }
反序列化功能:
CarCollection cars = null; string path = "cars.xml"; XmlSerializer serializer = new XmlSerializer(typeof(CarCollection)); StreamReader reader = new StreamReader(path); cars = (CarCollection)serializer.Deserialize(reader); reader.Close();
稍微调整一下的xml(我需要添加一个新元素来包装
1020 Nissan Sentra 1010 Toyota Corolla 1111 Honda Accord
你有两种可能性.
C:\path\to\xml\file.xml
打开开发人员命令提示符
您可以在Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
或中找到它.如果您有Windows 8,只需在" 开始"屏幕中键入开发人员命令提示符即可
通过键入将位置更改为XML文件目录 cd /D "C:\path\to\xml"
通过键入来创建xml文件中的XSD文件xsd file.xml
键入即可创建C#类xsd /c file.xsd
就是这样!您已从xml文件生成C#类C:\path\to\xml\file.cs
将XML文件的内容复制到剪贴板
添加到您的解决方案新的空类文件(Shift+ Alt+ C)
打开该文件并单击菜单 Edit > Paste special > Paste XML As Classes
就是这样!
这个助手类的用法非常简单:
using System;
using System.IO;
using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
using System.Xml;
using System.Xml.Serialization;
namespace Helpers
{
internal static class ParseHelpers
{
private static JavaScriptSerializer json;
private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }
public static Stream ToStream(this string @this)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(@this);
writer.Flush();
stream.Position = 0;
return stream;
}
public static T ParseXML(this string @this) where T : class
{
var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
}
public static T ParseJSON(this string @this) where T : class
{
return JSON.Deserialize(@this.Trim());
}
}
}
你现在要做的就是:
public class JSONRoot
{
public catalog catalog { get; set; }
}
// ...
string xml = File.ReadAllText(@"D:\file.xml");
var catalog1 = xml.ParseXML();
string json = File.ReadAllText(@"D:\file.json");
var catalog2 = json.ParseJSON();
以下代码段应该可以解决问题(您可以忽略大多数序列化属性):
public class Car { public string StockNumber { get; set; } public string Make { get; set; } public string Model { get; set; } } [XmlRootAttribute("Cars")] public class CarCollection { [XmlElement("Car")] public Car[] Cars { get; set; } }
...
using (TextReader reader = new StreamReader(path)) { XmlSerializer serializer = new XmlSerializer(typeof(CarCollection)); return (CarCollection) serializer.Deserialize(reader); }
看看这是否有帮助:
[Serializable()] [System.Xml.Serialization.XmlRootAttribute("Cars", Namespace = "", IsNullable = false)] public class Cars { [XmlArrayItem(typeof(Car))] public Car[] Car { get; set; } }
.
[Serializable()] public class Car { [System.Xml.Serialization.XmlElement()] public string StockNumber{ get; set; } [System.Xml.Serialization.XmlElement()] public string Make{ get; set; } [System.Xml.Serialization.XmlElement()] public string Model{ get; set; } }
并且没有使用visual studio附带的xsd.exe程序来创建基于该xml文件的模式文档,然后再次使用它来创建基于模式文档的类.
我不认为.net是"对反序列化数组的挑剔".第一个xml文档格式不正确.没有根元素,虽然它看起来像.规范的xml文档具有根和至少1个元素(如果有的话).在你的例子中:
<-- well, the root <-- an element (not a root), it being an array <-- an element, it being an array item ...
如果您的.xml文件已在磁盘中的某个位置生成并且您已使用过,请尝试此代码块List
:
//deserialization XmlSerializer xmlser = new XmlSerializer(typeof(List- )); StreamReader srdr = new StreamReader(@"C:\serialize.xml"); List
- p = (List
- )xmlser.Deserialize(srdr); srdr.Close();`
注意:C:\serialize.xml
是我的.xml文件的路径.您可以根据需要进行更改.
除了事实之外,Kevin的anser很好,在现实世界中,您通常无法改变原始XML以满足您的需求.
原始XML也有一个简单的解决方案:
[XmlRoot("Cars")] public class XmlData { [XmlElement("Car")] public ListCars{ get; set; } } public class Car { public string StockNumber { get; set; } public string Make { get; set; } public string Model { get; set; } }
然后你可以简单地打电话:
var ser = new XmlSerializer(typeof(XmlData)); XmlData data = (XmlData)ser.Deserialize(XmlReader.Create(PathToCarsXml));
尝试使用此通用类进行Xml序列化和反序列化。
public class SerializeConfigwhere T : class { public static void Serialize(string path, T type) { var serializer = new XmlSerializer(type.GetType()); using (var writer = new FileStream(path, FileMode.Create)) { serializer.Serialize(writer, type); } } public static T DeSerialize(string path) { T type; var serializer = new XmlSerializer(typeof(T)); using (var reader = XmlReader.Create(path)) { type = serializer.Deserialize(reader) as T; } return type; } }