[英]Reading Data Sets from XML c#
我有一個簡單的類,我正在設計在托管網站上記錄消息。
為了存儲消息,我創建了這個簡單的類結構:
public class StoredMsg {
public StoredMsg() {
}
public string From { get; set; }
public string Date { get; set; }
public string Message { get; set; }
}
將使用StoredMessages : List<StoredMsg>
類編寫和讀回這些消息。
這是Read
方法的原始格式:
public void Read() {
//string xmlPath = WebPage.Server.MapPath(XML_PATH);
if (File.Exists(xmlPath)) {
using (var xr = new XmlTextReader(xmlPath)) {
StoredMsg item = null;
while (xr.Read()) {
if (xr.NodeType == XmlNodeType.Element) {
if (xr.Name == HEAD) {
if (item != null) {
this.Add(item);
}
item = new StoredMsg();
} else if (xr.Name == FROM) {
item.From = xr.ReadElementString();
} else if (xr.Name == DATE) {
item.Date = xr.ReadElementString();
} else if (xr.Name == MESSAGE) {
item.Message = xr.ReadElementString();
}
}
}
xr.Close();
}
}
}
Write
方法最初采用以下格式:
public void Write(StoredMsg item) {
using (var stream = File.Open(xmlPath, FileMode.Append, FileAccess.Write, FileShare.Read)) {
using (var xw = new System.Xml.XmlTextWriter(stream, Encoding.UTF8)) {
xw.WriteStartElement(HEAD);
{
xw.WriteWhitespace("\r\n\t");
xw.WriteElementString(FROM, item.From);
xw.WriteWhitespace("\r\n\t");
xw.WriteElementString(DATE, item.Date);
xw.WriteWhitespace("\r\n\t");
xw.WriteElementString(MESSAGE, item.Message);
xw.WriteWhitespace("\r\n");
}
xw.WriteEndElement();
xw.WriteWhitespace("\r\n");
}
stream.Close();
}
}
問題是Read
方法不喜歡我的XML結構中的東西,所以我的列表總是空的。
在托管網站上很難對此進行故障排除,因此我開始在網上查看示例,看看我可能做錯了什么。
在我的搜索過程中,我找到了Microsoft的如何:將對象數據寫入XML文件(C#和Visual Basic) ,這向我展示了簡化Write
方法的簡化方法:
private XmlSerializer serializer;
public StoredMessages() {
serializer = new XmlSerializer(typeof(StoredMsg));
}
public void Write(StoredMsg item) {
using (var file = new StreamWriter(xmlPath, true)) {
serializer.Serialize(file, item);
}
}
對我來說,那就是簡約和優雅!
對此感到高興,我繼續使用Microsoft的如何:從XML文件(C#和Visual Basic)讀取對象數據 ,因此我也可以實現它。
我似乎能做的最好的事情是寫下我的方法:
public void Read() {
if (File.Exists(xmlPath)) {
using (var file = new StreamReader(xmlPath)) {
// How do I handle multiple nodes?
// http://msdn.microsoft.com/en-us/library/vstudio/ms172872.aspx
var item = (StoredMsg)serializer.Deserialize(file);
this.Add(item);
}
}
}
我很有興趣看到有人告訴我如何閱讀Linq to XML中的所有項目,我會給出+1,但這里的問題是如何使用上面的Read
技術讀取我的所有數據。
是不是我錯誤地將反序列化的對象轉換為StoredMsg
而不是其他東西? 如果是這樣,其他什么會是什么 ?
StoredMsg[]
? List<object>
? StoredMessages
? 感謝閱讀所有這些,我希望我的代碼對其他人清晰可讀。
示例數據作為屏幕截圖提供,以防止其他人輕易抓取我的電子郵件地址:
這是更通用的方法,不,你可以將任何對象傳遞給讀/寫
void Write<T>(Stream s,T obj)
{
var serializer = new XmlSerializer(typeof(T));
serializer.Serialize(s, obj);
}
T Read<T>(Stream s)
{
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(s);
}
例如
StoredMsg[] msgs = .....;
Write(stream, msgs);
要么
StoredMsg[] msgs = Read<StoredMsg[]>(stream());
編輯
void Write<T>(string fileName, T obj)
{
using (var stream = File.Create(fileName))
{
Write(stream, obj);
}
}
T Read<T>(string fileName)
{
using (var stream = File.Open(fileName, FileMode.Open))
{
return Read<T>(stream);
}
}
假設有類似的XML結構:
<Messages>
<MessageHead>
<From>Stackoverflow</From>
<Date>09/05/2013</Date>
<Message>Hello world</Message>
</MessageHead>
<MessageHead>
<From>Stackoverflow</From>
<Date>09/05/2013</Date>
<Message>Second Message</Message>
</MessageHead>
</Messages>
您可以使用LINQ to XML查詢將每個MessageHead
子節點作為單個消息讀取:
var nodes = (from n in xml.Descendants("MessageHead")
select new
{
From = (string)n.Element("From").Value,
Date = (string)n.Element("Date").Value,
Message = (string)n.Element("Message").Value
}).ToList();
這給出了兩個包含以下節點的列表:
從那里可以很容易地將它們映射到您的班級,例如
foreach (var n in nodes)
{
StoredMessage s = new StoredMessage();
s.from = n.From;
s.date = n.Date;
s.message = n.Message;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.