.NET XML シリアル化
-
09-06-2019 - |
質問
私は XML にシリアル化するために使用されるクラスのセットに取り組んでいます。XML は私によって管理されておらず、かなりよく整理されています。残念ながら、ネストされたノードのセットがいくつかあり、それらの一部の目的は、子のコレクションを保持することだけです。XML シリアル化に関する私の現在の知識に基づくと、これらのノードには別のクラスが必要です。
クラスを 1 つだけではなく一連の 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; }
}
他のヒント
ユーザーを 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( "Employee")] Public Class Employee {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();
}
}
}
}