Сериализация .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
объект.
Есть кто-нибудь, кто знает это лучше меня?(не лги, я знаю, что они есть).
Решение
Вы не пользуетесь XmlSerializer - сериализатор?Это чертовски хорошо, и делать подобные вещи действительно легко (я использую его довольно часто!).
Вы можете просто украсить свойства своего класса некоторыми атрибутами, а все остальное будет сделано за вас..
Рассматривали ли вы возможность использования XmlSerializer или есть какая-то особая причина, почему бы и нет?
Вот фрагмент кода всей работы, необходимой для сериализации приведенного выше (в обоих направлениях):
[XmlArray("users"),
XmlArrayItem("user")]
public List<User> Users
{
get { return _users; }
}
Другие советы
Вам нужно будет только, чтобы пользователи были определены как массив пользовательских объектов.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("Employee")] открытый класс Employee { имя частной строки = "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) должен быть сериализуемым.Попробуйте [Serializable(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();
}
}
}
}