.NET XML 序列化
-
09-06-2019 - |
题
我正在研究一组将用于序列化为 XML 的类。XML 不受我控制,而且组织得相当好。不幸的是,有几组嵌套节点,其中一些的目的只是保存其子节点的集合。根据我目前对 XML 序列化的了解,这些节点需要另一个类。
有没有一种方法可以使类序列化为一组 XML 节点,而不仅仅是一个。因为我觉得我说得很清楚了,假设我们有 xml:
<root>
<users>
<user id="">
<firstname />
<lastname />
...
</user>
<user id="">
<firstname />
<lastname />
...
</user>
</users>
<groups>
<group id="" groupname="">
<userid />
<userid />
</group>
<group id="" groupname="">
<userid />
<userid />
</group>
</groups>
</root>
理想情况下,3节课最好。一类 root
与集合 user
和 group
对象。然而,我能想到的最好的是我需要一堂课 root
, users
, user
, groups
和 group
, , 在哪里 users
和 groups
仅包含以下集合 user
和 group
分别是,和 root
包含一个 users
, , 和 groups
目的。
有谁比我更了解吗?(别撒谎,我知道有)。
解决方案
你没有使用 Xml序列化器?它非常好,让做这样的事情变得非常容易(我经常使用它!)。
您可以简单地用一些属性来装饰您的类属性,其余的一切都为您完成。
您是否考虑过使用 XmlSerializer 或者是否有特殊原因不使用?
以下是序列化上述内容所需的所有工作的代码片段(两种方式):
[XmlArray("users"),
XmlArrayItem("user")]
public List<User> Users
{
get { return _users; }
}
其他提示
您只需将 Users 定义为 User 对象的数组。XmlSerializer 将为您适当地呈现它。
请参阅此链接的示例:http://www.informit.com/articles/article.aspx?p=23105&seqNum=4
此外,我建议使用 Visual Studio 生成 XSD 并使用命令行实用程序 XSD.EXE 为您吐出类层次结构,如下所示: http://quickstart.developerfusion.co.uk/quickstart/howto/doc/xmlserialization/XSDToCls.aspx
我当天写了这门课,是为了做我认为与你想做的事情类似的事情。您可以对希望序列化为 XML 的对象使用此类的方法。例如,给定一名员工...
使用实用程序;使用 System.Xml.Serialization;
xmlroot(“雇员”)]公共类员工{private string name =“ steve”;
[XmlElement("Name")]
public string Name { get { return name; } set{ name = value; } }
public static void Main(String[] args)
{
Employee e = new Employee();
XmlObjectSerializer.Save("c:\steve.xml", e);
}
}
这段代码应该输出:
<Employee>
<Name>Steve</Name>
</Employee>
对象类型(Employee)必须是可序列化的。尝试[可序列化(true)]。我在某个地方有这个代码的更好版本,我编写它时只是在学习。无论如何,请查看下面的代码。我在一些项目中使用它,所以它绝对有效。
using System;
using System.IO;
using System.Xml.Serialization;
namespace Utilities
{
/// <summary>
/// Opens and Saves objects to Xml
/// </summary>
/// <projectIndependent>True</projectIndependent>
public static class XmlObjectSerializer
{
/// <summary>
/// Serializes and saves data contained in obj to an XML file located at filePath <para></para>
/// </summary>
/// <param name="filePath">The file path to save to</param>
/// <param name="obj">The object to save</param>
/// <exception cref="System.IO.IOException">Thrown if an error occurs while saving the object. See inner exception for details</exception>
public static void Save(String filePath, Object obj)
{
// allows access to the file
StreamWriter oWriter = null;
try
{
// Open a stream to the file path
oWriter = new StreamWriter(filePath);
// Create a serializer for the object's type
XmlSerializer oSerializer = new XmlSerializer(obj.GetType());
// Serialize the object and write to the file
oSerializer.Serialize(oWriter.BaseStream, obj);
}
catch (Exception ex)
{
// throw any errors as IO exceptions
throw new IOException("An error occurred while saving the object", ex);
}
finally
{
// if a stream is open
if (oWriter != null)
{
// close it
oWriter.Close();
}
}
}
/// <summary>
/// Deserializes saved object data of type T in an XML file
/// located at filePath
/// </summary>
/// <typeparam name="T">Type of object to deserialize</typeparam>
/// <param name="filePath">The path to open the object from</param>
/// <returns>An object representing the file or the default value for type T</returns>
/// <exception cref="System.IO.IOException">Thrown if the file could not be opened. See inner exception for details</exception>
public static T Open<T>(String filePath)
{
// gets access to the file
StreamReader oReader = null;
// the deserialized data
Object data;
try
{
// Open a stream to the file
oReader = new StreamReader(filePath);
// Create a deserializer for the object's type
XmlSerializer oDeserializer = new XmlSerializer(typeof(T));
// Deserialize the data and store it
data = oDeserializer.Deserialize(oReader.BaseStream);
//
// Return the deserialized object
// don't cast it if it's null
// will be null if open failed
//
if (data != null)
{
return (T)data;
}
else
{
return default(T);
}
}
catch (Exception ex)
{
// throw error
throw new IOException("An error occurred while opening the file", ex);
}
finally
{
// Close the stream
oReader.Close();
}
}
}
}