假设我在同一个程序集中有两个不同的xml文件作为embedded-resource:
x.xml
<car brand="Hummer">
<type ... />
<chasis ... />
</car>
y.xml
<shark species="HammerHead">
<color ... />
<maxLen .... />
</shark>
我有两个课程Car.cs
和Shark.cs
来帮助反序列化它们。
将它们反序列化为两个不同且独立的对象的技术是什么?
以下代码一次只能处理一种类型。不是吗?
string[] manifestResourceNames = assembly.GetManifestResourceNames();
foreach (string mrn in manifestResourceNames)
{
Stream stream = assembly.GetManifestResourceStream(mrn);
XmlSerializer serializer = new XmlSerializer(typeof(Car));
Car car = (Car)serializer.Deserialize(stream);
.... .... ....
}
并且,当此代码遇到Shark
- 类时,它将生成异常。
答案 0 :(得分:2)
为了使系统以任何方式可靠,您需要命名XML(无论如何,您应始终使用命名空间XML - 但我会为您节省咆哮)。因此:
<car xmlns="http://schemas.cars.org/car" brand="Hummer">
<type /> <chassis />
</car>
<shark xmlns="http://schemas.ocenia.org/predator">
<lazer-beams>1</lazer-beams>
<awesome>Hell yeah.</awesome>
</shark>
您的C#XML序列化属性将变为:
[XmlRoot("Car", Namespace=CarNamespaceUri)]
public class Car
{
public const string CarNamespaceUri = "http://schemas.cars.org/car";
// ...
}
在此之后你会写一些XmlSerializerManager
的内容。这将保留内部Dictionary<Tuple<string, string>, XmlSerializer>
- 您可以通过反射填充(查找应用了XmlRootAttribute
的所有类型,并根据Namespace, LocalName
创建元组并实例化XmlSerializer
那种类型)。这可能是一个静态类。
要反序列化任何元素,只需在字典中查找其名称和命名空间即可检索XmlSerializer
实例。例如:
public static T Deserialize<T>(XElement element)
{
return (T)Deserialize(element);
}
public static object Deserialize(XElement element)
{
// Remember to do more elaborate checks etc.
using(var r = element.CreateReader())
{
return _serializers[Tuple.Create(element.Name.NamespaceName, element.Name.LocalName)].Deserialize(r);
}
}
答案 1 :(得分:1)
查看XmlSerializer课程。来自MSDN:
将对象序列化和反序列化到XML文档中或从XML文档中反序列化。该 XmlSerializer使您可以控制对象如何编码为XML。
如果类结构与给定的ML不完全匹配,即属性名称和XML元素之间没有关联,则have to use attributes to provide a suitable mapping。
关于上面的代码,构造XmlSerializer
实例,使其序列化/反序列化单个类型。你需要创建这个类的单独实例,一个用于汽车,一个用于鲨鱼。
答案 2 :(得分:0)
您的代码只能处理一个类。
我使用此link来了解XMLserializer。在这里你可以找到一些很好的例子。在最后一个示例中,此代码显示为:
static List<Movie> DeserializeFromXML()
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Movie>));
TextReader textReader = new StreamReader(@"C:\movie.xml");
List<Movie> movies;
movies = (List<Movie>)deserializer.Deserialize(textReader);
textReader.Close();
return movies;
}
你可以重建它以使用你的.xml文件:
static List<Car> DeserializeCar()
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Car>));
TextReader textReader = new StreamReader("./car.xml");
List<Car> cars;
cars= (List<Car>)deserializer.Deserialize(textReader);
textReader.Close();
return cars;
}
static List<Car> DeserializeShark()
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Shark>));
TextReader textReader = new StreamReader("./shark.xml");
List<Shark> shark;
shark= (List<Shark>)deserializer.Deserialize(textReader);
textReader.Close();
return shark;
}
通过调用这两个函数,您可以获得两个类
答案 3 :(得分:0)
我会创建一个类似于以下
的抽象基类 public abstract class Model<T>
{
public static T GetFromXml(String path)
{
if (!File.Exists(path))
return null;
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(File.OpenRead(path));
}
}
public class Car : Model<Car>
{
public String Brand { get; set; }
public String Type { get; set; }
public String Chasis { get; set; }
}
public class Shark : Model<Shark>
{
public String Species { get; set; }
public String Color { get; set; }
public long MaxLength { get; set; }
}
您可以从任何子类
轻松访问静态方法Car myCar = Car.GetFromXml("a.xml");
Shark greatWhite = Shark.GetFromXml("b.xml");
希望这就是你所期待的。
和Thorsten