Xmlシリーズ化初体験
63620 ワード
多くの場合、プロジェクトを行うときにデータテストが必要です.例えば、ページングを行うときにページングテストを行うには、データソースをテストするためにデータが必要ですか?データベースは間違いなく良い選択ですが、データベースを作成してテスト用のテーブルを作成すると、少し面倒になりますか?個人的にはちょっと面倒だと思いますが...
最近自分が退屈でもjQueryでページ分けのコントロールをして、テストの时にこの问题に出会った:データソースの问题.データベースでテストしたいと思っていましたが、面倒を恐れて他の良い方法で実現できるかどうか考えていました.データテストが必要なような問題は後で発生するので、今良い方法を探して解決したいと思っていました.自分のニーズに合ったxmlシリーズ化を書く方法があります.
シリーズ化xml、最初に思いついたのは.Net FrameworkのXmlSerializer、コードは以下の通りです.
以上のように、実はとても简単で、テストしてやっとこれが自分の望む効果を実现することができないことを発见しました...
だから仕方なく自分で簡単な方法を書きました.
次に、オブジェクトインスタンスの作成方法を示します.
N個のデータを保存するため、以下のようにXmlファイルのフォーマットをカスタマイズしました.
Entityはxmlのルートノードです.
実は考え方はとても簡単で、シリーズ化するオブジェクトとファイルの経路を入ってきて、プロジェクトの中でこのxmlファイルが存在するかどうかを判断して、もし存在しないならば作成して、以前xmlファイルのフォーマットに制限があると言って(そのフォーマットは上述のように)、それからオブジェクトの属性の名前/値に基づいてxml要素を作成して、該当する判断属性が参照オブジェクトであるかどうか、該当する参照オブジェクトを作成している場合.
ほほほ、この表現力はお世辞にも言えない.あら...反系列化についてはあまり言わないで、コードに直接あげます.
シリーズ化と反シリーズ化が実現した後、それに応じてシリーズ化後のファイルを追加、削除、変更、検索操作を行い、これらは整理し、後でソースコードをアップします.
以下は、シリーズ化されたファイルです.
反系列化された後はオブジェクトです
最近自分が退屈でも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
>
反系列化された後はオブジェクトです