Xmlシリーズ化初体験

63620 ワード

多くの場合、プロジェクトを行うときにデータテストが必要です.例えば、ページングを行うときにページングテストを行うには、データソースをテストするためにデータが必要ですか?データベースは間違いなく良い選択ですが、データベースを作成してテスト用のテーブルを作成すると、少し面倒になりますか?個人的にはちょっと面倒だと思いますが...
最近自分が退屈でもjQueryでページ分けのコントロールをして、テストの时にこの问题に出会った:データソースの问题.データベースでテストしたいと思っていましたが、面倒を恐れて他の良い方法で実現できるかどうか考えていました.データテストが必要なような問題は後で発生するので、今良い方法を探して解決したいと思っていました.自分のニーズに合ったxmlシリーズ化を書く方法があります.
シリーズ化xml、最初に思いついたのは.Net FrameworkのXmlSerializer、コードは以下の通りです.

  
    
/// <summary>
///
/// </summary>
/// <param name="obj"> </param>
/// <param name="filepath"> </param>
public static bool Save( object obj, string filepath)
{
bool success = false ;
FileStream fs
= null ;
try
{
fs
= new FileStream(filepath, FileMode.Create, FileAccess.ReadWrite);
XmlSerializer serializer
= new XmlSerializer(obj.GetType());
serializer.Serialize(fs, obj);
success
= true ;
}
catch (Exception ex)
{

throw ex;
}
finally
{
if (fs != null )
{
fs.Close();
fs.Dispose();
}
}
return success;
}

/// <summary>
///
/// </summary>
/// <param name="type"> </param>
/// <param name="filepath"> </param>
/// <returns></returns>
public static object Load(Type type, string filepath)
{
FileStream fs
= null ;
try
{
fs
= new FileStream(filepath, FileMode.Open, FileAccess.ReadWrite);
XmlSerializer serializer
= new XmlSerializer(type);
return serializer.Deserialize(fs);
}
catch (Exception ex)
{

throw ex;
}
finally
{
if (fs != null )
{
fs.Close();
fs.Dispose();
}
}
}

以上のように、実はとても简単で、テストしてやっとこれが自分の望む効果を実现することができないことを発见しました...
だから仕方なく自分で簡単な方法を書きました.

  
    
/// <summary>
/// object xml
/// </summary>
/// <param name="obj"> </param>
/// <param name="filename"> </param>
public static XmlDocument XmlSerialize( string filename, object obj)
{
FileInfo fileInfo
= new FileInfo(filename);
if ( ! fileInfo.Exists) //
{
CreateFile(filename);
}
XmlDocument xmlDoc
= new XmlDocument();
string name = obj.GetType().Name;
xmlDoc.Load(filename);
XmlNode node
= xmlDoc.SelectSingleNode( " Entity " );
CreateSubElement(
ref xmlDoc, node, obj, name);
xmlDoc.Save(filename);
return xmlDoc;
}

/// <summary>
///
/// </summary>
/// <param name="xmlDoc"> xml </param>
/// <param name="obj"> </param>
public static void CreateSubElement( ref XmlDocument xmlDoc, XmlNode node, object obj, string name)
{
XmlElement root
= xmlDoc.CreateElement(name); //
node.AppendChild(root);
foreach (var item in obj.GetType().GetProperties())
{
string value = " Null " ;
var objValue
= item.GetValue(obj, null );
var proName
= item.Name;
Type type
= item.PropertyType;
bool isClass = IsClass(type); //
if (isClass)
{
object o = CreateExample(type);
string filename = XmlHelper.GetFileName(type.Name);
FileInfo fileInfo
= new FileInfo(filename);
if ( ! fileInfo.Exists) //
{
CreateFile(filename);
}
CreateSubElement(
ref xmlDoc, root, o, type.Name);
continue ;
}
if (objValue != null )
{
value
= objValue.ToString();
}
XmlElement element
= xmlDoc.CreateElement(proName);
element.SetAttribute(
" DataType " , item.PropertyType.Name); //
element.InnerText = value;
root.AppendChild(element);
}
}

/// <summary>
/// TypeCode
/// </summary>
/// <param name="type"> </param>
/// <returns></returns>
public static bool IsClass(Type type)
{
string [] typeCodeNameArray = Enum.GetNames( typeof (TypeCode));
foreach ( string item in typeCodeNameArray)
{
if (type.Name == item)
{
return false ;
}
}
return true ;
}

  
    
/// <summary>
/// Xml
/// </summary>
/// <param name="filename"> </param>
public static void CreateFile( string filename)
{
FileStream stream
= null ;
XmlWriter xmlWriter
= null ;
try
{
stream
= new FileStream(filename, FileMode.Create, FileAccess.ReadWrite);
XmlDocument xmlDoc
= new XmlDocument();
XmlDeclaration declaration
= xmlDoc.CreateXmlDeclaration( " 1.0 " , " utf-8 " , null );
XmlNode rootNode
= xmlDoc.CreateNode(XmlNodeType.Element, null , " Entity " , null );
rootNode.InnerText
= "" ;
xmlDoc.AppendChild(declaration);
xmlDoc.InsertAfter(rootNode, declaration);
xmlWriter
= XmlWriter.Create(stream);
xmlDoc.WriteTo(xmlWriter);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (xmlWriter != null ) xmlWriter.Close();
if (stream != null ) stream.Close();
}
}

次に、オブジェクトインスタンスの作成方法を示します.

  
    
/// <summary>
///
/// </summary>
/// <param name="type"> </param>
/// <returns></returns>
public static object CreateExample(Type type)
{
object obj = Activator.CreateInstance(type);
return obj;
}

N個のデータを保存するため、以下のようにXmlファイルのフォーマットをカスタマイズしました.

  
    
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< Entity >
</ Entity >

Entityはxmlのルートノードです.
実は考え方はとても簡単で、シリーズ化するオブジェクトとファイルの経路を入ってきて、プロジェクトの中でこのxmlファイルが存在するかどうかを判断して、もし存在しないならば作成して、以前xmlファイルのフォーマットに制限があると言って(そのフォーマットは上述のように)、それからオブジェクトの属性の名前/値に基づいてxml要素を作成して、該当する判断属性が参照オブジェクトであるかどうか、該当する参照オブジェクトを作成している場合.
ほほほ、この表現力はお世辞にも言えない.あら...反系列化についてはあまり言わないで、コードに直接あげます.

  
    
/// <summary>
/// xml
/// </summary>
/// <param name="type"> </param>
/// <param name="xmlNode"> xml </param>
/// <returns></returns>
public static object XmlDeserialize(Type type,XmlNode xmlNode)
{
XmlElement xe
= (XmlElement)xmlNode;
object parentObj = CreateExample(type);
foreach (var parentItem in parentObj.GetType().GetProperties())
{
var parentSetobj
= parentObj.GetType().GetProperty(parentItem.Name);
XmlElement xmlElement
= (XmlElement)xe.SelectSingleNode(parentItem.Name);
Type parentType
= parentItem.PropertyType;
bool isClass = IsClass(parentType);
if (isClass)
{
object subObj = CreateExample(parentType);
string subName = subObj.GetType().Name;
XmlNode subNode
= xe.SelectSingleNode(subName);
foreach (var subItem in subObj.GetType().GetProperties())
{
XmlElement subxl
= (XmlElement)subNode;
var subSetobj
= subObj.GetType().GetProperty(subItem.Name);
Type proType
= subItem.PropertyType;
if (IsClass(proType))
{
subObj
= XmlDeserialize(subObj.GetType(), subNode);
continue ;
}
object value = Convert.ChangeType(subxl.SelectSingleNode(subItem.Name).InnerText, proType);
subSetobj.SetValue(subObj, value,
null );
}
parentSetobj.SetValue(parentObj, subObj,
null );
continue ;
}
object parentValue = Convert.ChangeType(xmlElement.InnerText, parentType);
parentSetobj.SetValue(parentObj, parentValue,
null );
}
return parentObj;
}

シリーズ化と反シリーズ化が実現した後、それに応じてシリーズ化後のファイルを追加、削除、変更、検索操作を行い、これらは整理し、後でソースコードをアップします.
以下は、シリーズ化されたファイルです.

  
    
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< Entity >
< Student >
< StudentNo DataType = " String " > 001 </ StudentNo >
< Name DataType = " String " > MrChen </ Name >
< Sex DataType = " String " > </ Sex >
< BirthDay DataType = " DateTime " > 1989 - 5 - 14 22 : 05 : 01 </ BirthDay >
< Course >
< CourseNo DataType = " String " > Null </ CourseNo >
< CourseName DataType = " String " > Null </ CourseName >
< Id DataType = " String " > ab0a7aa2 - 4295 - 4fe6 - 910c - 1e61c47a942c </ Id >
< CreateTime DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 01 </ CreateTime >
< IsDelete DataType = " Boolean " > False </ IsDelete >
< Version DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 01 </ Version >
</ Course >
< Id DataType = " String " > 295afde9 - b5ce - 465c - b267 - ae948cce3ec7 </ Id >
< CreateTime DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 01 </ CreateTime >
< IsDelete DataType = " Boolean " > False </ IsDelete >
< Version DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 01 </ Version >
</ Student >
< Student >
< StudentNo DataType = " String " > 002 </ StudentNo >
< Name DataType = " String " > MrChen </ Name >
< Sex DataType = " String " > </ Sex >
< BirthDay DataType = " DateTime " > 1989 - 5 - 14 22 : 05 : 43 </ BirthDay >
< Course >
< CourseNo DataType = " String " > Null </ CourseNo >
< CourseName DataType = " String " > Null </ CourseName >
< Id DataType = " String " > fb674255 - 0af9 - 4863 - b2dc - b29b112b4ad5 </ Id >
< CreateTime DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 43 </ CreateTime >
< IsDelete DataType = " Boolean " > False </ IsDelete >
< Version DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 43 </ Version >
</ Course >
< Id DataType = " String " > 8ccafe8c - 5d7b - 4e1d - 9721 - c8393e392929 </ Id >
< CreateTime DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 43 </ CreateTime >
< IsDelete DataType = " Boolean " > False </ IsDelete >
< Version DataType = " DateTime " > 2011 - 5 - 14 22 : 05 : 43 </ Version >
</ Student >
</ Entity >

反系列化された後はオブジェクトです