.NET XML Seralization
-
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 ("الموظف")] موظف الطبقة العامة {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>
يجب أن يكون نوع الكائن (الموظف) قابلاً للتسلسل.جرب [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();
}
}
}
}