項目中有時候要用XML做爲數據源,所以須要定義XML文件和相應的類,最佳方法是首先定義XSD,而後自動生成實體類,最後生成XML和填充數據;讀取XML數據源的時候,首先用XSD驗證XML數據格式,而後自動讀入實體類使用。
定義XSD的過程就是相似設計表結構的過程,兩者也能夠相互轉化。
本文討論瞭如何定義XSD文件(XML Schema),而後自動生成實體類,最後生成XML的過程,以及如何根據XSD驗證XML文件的合法性。以供你們作項目時參考。
1. 首先在VS2005中添加一個XSD文件。例子XSD能夠參考:
http://www.15seconds.com/issue/031209.htmhtml
http://www.cduce.org/manual_schema_samples.html工具
2. 使用VS2005工具XSD.exe(SDK\v2.0\Bin\xsd.exe)自動生成實體類:spa
xsd /c /namespace:myCompany /language:CS temp1.xsd設計
也能夠生成DataSet類型的類:htm
xsd /dataset /language:CS temp1.xsdblog
( 類文件和XSD之間能夠相互轉換,也就是說,你也能夠先生成類,而後自動生成XSD)get
自動讀取XML數據到實體類:
string
XmlSerializer xs = new XmlSerializer(typeof(myClassType));
using (FileStream fs = new FileStream(XmlFilePath, FileMode.Open))
{
return (myClassType)xs.Deserialize(fs);
}
3. 如何由XML生成XSD?
- 能夠用工具,如XMLSpy,首先打開XML, 而後DTD/Schema -> Generate DTD/Schema, 選擇W3c Sehcma便可。it
- 此方法不必定能生成確切知足需求的XSD,另需修改。io
4. 如何由XSD生成XML?
- 能夠用其餘工具,如XMLSpy,DTD/Schema -> Generate sample XML file...
- 能夠由XSD生成類,而後寫代碼實例化這個類,最後序列化爲XML
- 如何自動給類每一個屬性設置一個空值:(用反射的方法)
代碼示例:
/// <summary>
/// Get all properties and set default value
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="item">Object</param>
private static void ReflctProperties<T>(T item)
{
PropertyInfo[] pty = typeof(T).GetProperties();
Type t = item.GetType();
if (pty != null)
{
foreach (PropertyInfo info in pty)
{
if (!info.CanWrite) continue;
if (info.PropertyType == typeof(String))
{
t.GetProperty(info.Name).SetValue(item, String.Empty, null);
}
if (info.PropertyType == typeof(Boolean))
{
t.GetProperty(info.Name).SetValue(item, true, null);
}
}
}
}
- 反射讀取類的屬性:
public static object GetProperty<T>(T item, string PropertyName)
{
PropertyInfo propertyInfo = item.GetType().GetProperty(PropertyName);
if (propertyInfo != null)
{
return propertyInfo.GetValue(item, null);
}
return null;
}
- 如何序列化爲XML?
/// <summary>
/// Serialize class instance to XML file
/// </summary>
/// <typeparam name="T">type</typeparam>
/// <param name="XMLFileToCreate">XMLFileToCreate</param>
/// <param name="instance">class instance</param>
public void Serialize<T>(string XMLFileToCreate, T instance)
{
if (instance == null) return;
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StreamWriter sw = new StreamWriter(XMLFileToCreate))
{
xs.Serialize(sw, instance);
}
}
(Link: 使用XMLSerializer類持久化數據 )
5. 如何使用XSD來驗證XML文件合法性:
- 使用XMLSpy,首先Assign XSD,而後驗證 (其實就是設置XML裏面引用的schema,注意schema可能引用其餘的schema)
- 代碼中驗證:
#region Validate XML against XSD
public class Validator
{
private string errMsg;
/// <summary>
/// validation Error Msg
/// </summary>
public string validationErrMsg
{
get { return errMsg; }
set { errMsg = value; }
}
/// <summary>
/// Validate XML against schema
/// </summary>
/// <param name="XSD"></param>
/// <param name="XMLFile"></param>
/// <param name="LocationDefined"></param>
/// <returns></returns>
public bool Validate(string XSD, string XMLFile, bool LocationDefined)
{
bool isValid = true;
try
{
Stream schemaFile = null;
XmlReaderSettings settings = new XmlReaderSettings();
ValidationEventHandler SchemaValidationEventHandler = new ValidationEventHandler(ValidationCallBack);
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.AllowXmlAttributes;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += SchemaValidationEventHandler;
if (LocationDefined == true)
{
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
}
else
{
schemaFile = new FileStream(XSD, FileMode.Open);
XmlSchema tmsSchema = XmlSchema.Read(schemaFile, SchemaValidationEventHandler);
settings.Schemas.Add(tmsSchema);
}
using (XmlReader reader = XmlReader.Create(XMLFile, settings))
{
string test;
while (reader.Read() && isValid == true)
{
test = reader.Name;
}
};
if (schemaFile != null)
{
schemaFile.Close();
}
}
catch (Exception e)
{
validationErrMsg += "Exception occured when validating. " + e.Message;
isValid = false;
}
return isValid;
}
/// <summary>
/// Display any warnings or errors.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void ValidationCallBack(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
{
validationErrMsg += "Matching schema not found. No validation occurred." + args.Message;
validationErrMsg = args.Message;
}
else
{
validationErrMsg += "\nValidation error: " + args.Message;
validationErrMsg = args.Message;
}
}
}
#endregion