//導出dataset數據到XML文件
//Author:Quietwalk
//2010-09-09
public bool ExportToXMl(DataSet ds, string strXMLPath)
{
//DirectoryInfo mobileDir = new DirectoryInfo(strXMLPath);
FileInfo XMLfile = new FileInfo(strXMLPath);
bool bReturnValue = false;
try
{
if (ds != null && ds.Tables.Count > 0 && XMLfile.Exists)
{
ds.WriteXml(strXMLPath, XmlWriteMode.WriteSchema);
bReturnValue = true;
}
}
catch(SqlCeException ex)
{
throw(ex);
}
return bReturnValue;
}
//XML 數據導入到 DataSet中
//Author:Quietwalk
//2010-09-09
public DataSet ImportFromXml(string fromPath)
{
FileInfo xmlFile = new FileInfo(fromPath);
DataSet dsXML =null;
if (xmlFile.Exists)
{
FileStream fsReadXml = new FileStream(fromPath, FileMode.Open);
XmlTextReader myXmlReader = new XmlTextReader(fsReadXml);
dsXML=new DataSet ();
dsXML.ReadXml(myXmlReader);
myXmlReader.Close();
}
return dsXML;
}
說明:
DateSet.ReadXML()
ReadXML缺省使用XmlReadMode.Auto方式讀取,這就給大數據量留下了低效率的伏筆。因為tb如果XML沒有Scheme,DataSet就會自己推算XML的結構,然后再加載,這就是低效的主要原因。讓DataSet推算不讓我們幫他算,因為DataSet已經提供了一個ReadXmlSchema方法。
dataset是這樣存儲的:table(0)中存放feature層的信息,包括fno等屬性,只有一行;
table(1)中包括attribute的信息包括ano等屬性,有兩行。如果attribute下還有其他子層,就依次放在 table(2)..中。 dataset讀取數據之后,可以與datagrid綁定進行顯示,綁定時可以針對dataset中的單個表,也可以一次綁定所有表。
1. 載入 xml 文件的格式要求
a. 不可以讀取空的文件.
如果使用 DataSet.ReadXml 載入一個空的文件, 將出現異常, 因為沒有根元素.
b. 可以讀取沒有 <?xml?> 頭的 xml 文件.
你的 xml 文件可以不包含 <?xml version="1.0" encoding="utf-8" ?> 這樣的代碼.
2. xml 文件的編碼格式
a. <?xml?> 頭中標記的編碼最好和文件自身的編碼一致.
在測試文件中, 我使用 utf-32 存儲標記為 utf-8 的 xml 文件, 或者反過來都導致了 DataSet 讀取文件異常. 雖然, 我并沒有對所有的編碼進行測試, 而且用 ASCII 存儲標記為 utf-8 的 xml 時, tb讀取不會出現異常, 只不過中文可能會出現亂碼, 最好還是保持編碼一致吧.
b. 采用 ASCII 存儲 xml 文件可能出現中文亂碼.
xml 自身是不支持 ASCII 的, 雖然讀取沒有異常, 但你讀取的信息可能是一堆"?".
3. XmlReadMode 參數對 DataSet 讀取 xml 文件的影響
a. 非典型 DataSet 如果包含架構, 并使用默認的 XmlReadMode.Auto 或者忽略此選項, 將只載入 xml 文件中符合架構的數據.
如果你的數據集中包含了架構信息, 例如定義了 S1, T1(Name string, Age int), Student(Name string, Age int), Teacher 4 個表, 數據集名稱為 TestDS, 命名空間為 http://tempuri.org/TestDS.xsd, 如果一個的 xml 文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<TestDS xmlns="http://tempuri.org/TestDS.xsd">
<Student>
<Name>小明</Name>
<Age>12</Age>
</Student>
<Teacher>
<Name>王老師</Name>
<Age>32</Age>
</Teacher>
<Room>
<ID>123</ID>
</Room>
</TestDS>
使用 DataSet.ReadXml 讀取此 xml 文件時, 第一個 Student 被讀取到 DataSet 的 Student 表中, 因為 xml 中 Student 對應的列名數據類型和 DataSet 架構一致. 第二個 Teacher 不會被讀取, DataSet 架構中雖然包含了表 Teacher, 但并沒有定義任何的列, 而 xml 中的 Teacher 包含了 Name, Age 兩個列. 第三個 Room 不會被讀取, 因為架構中不包含表 Room. 以上是針對非典型 DataSet 測試的結果, 典型 DataSet 應該也是如此, 有興趣的朋友可以自己測試一下.
b. 非典型 DataSet 如果不包含架構, 并使用默認的 XmlReadMode.Auto 或者忽略此選項, 將分析并采用 xml 文件的架構.
如果僅僅使用 new 創建了一個非典型 DataSet, 那么 DataSet 中尚未包含架構. 如果一個的 xml 文件如下:
<?xml version="1.0" encoding="utf-8" ?>
<TestDS xmlns="http://tempuri.org/TestDS.xsd">
<Room>
<ID>123</ID>
</Room>
<Room>
<ID>123</ID>
<Name>儲藏室</Name>
</Room>
</TestDS>
當 DataSet 讀取 xml 文件時, 將分析數據集名稱, 命名空間, 并針對每一條數據進行架構分析, 我想這一點很重要, 正如上面的文件中, 當讀取到第一個 Room 時, 分析得到需要 Room(ID) 這樣的表, 讀取第二個 Room 時, 會發現 Room 表的架構信息已經存在, 經過對比發現需要變更架構為 Room(ID, Name). 每一條數據除了架構分析以外, 還要進行可能的架構更改工作. 因此, 在效率上可能不及 a 中說到的情況.
c. 對于 XmlReadMode 的其余選項, 似乎并不用于 ReadXml 方法, 或者沒有實際效果.
4. 載入 xml 字符串, byte[] 數組到 DataSet
a. 使用 DataSet.ReadXml(new StringReader(string)) 可以將 xml 字符串載入到 DataSet.
xml 字符串應該是合法的, 如果在字符串的 <?xml?> 頭中指定 encoding, 那么指定任何編碼都可以讀取中文字符, 也就是說指定對于載入是沒有作用的.
b. 使用 DataSet.ReadXml(new MemoryStream(byte[])) 可以將 byte[] 數組表示的 xml 載入到 DataSet.
對于編碼, 載入 byte[] 數組和載入文件的要求是類似的, <?xml?> 頭中標記的編碼應該和 byte[] 數組的編碼一致, 最好不要采用 ASCII, 原因在上文中已經提到. 使用 Encoding.GetBytes 方法將字符串轉化為 byte[] 數組時, 編碼應該對照. 如果, 使用 Encoding.UTF8.GetBytes, 那么字符串中 <?xml?> 頭應該標記 uft-8, 另外, 也可以不標記 encoding, 結果是相同的.