《Windows Phone 7 程序设计》学习笔记(五)

先来看一段代码,我想先用序列化的方法把对象存为XML文件,再对该文件进行增删改查。

View Code
 1  public class Notes
 2     {
 3         XmlSerializer serializer = new XmlSerializer(typeof(NoteCollection));
 4 
 5         public void Save(NoteCollection noteCollection)
 6         {            
 7            using( IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
 8            {
 9                if (iso.FileExists("notes.xml"))
10                {
11                    IsolatedStorageFileStream stream = iso.CreateFile("notes.xml");
12                    StreamWriter writer = new StreamWriter(stream);
13                    serializer.Serialize(writer, noteCollection);
14                    writer.Close();
15                }
16          }
17         }
18 
19         public void AddToXml(Note note,NoteCollection noteCollection)
20         {
21             using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
22             {
23                 if (iso.FileExists("notes.xml"))
24                 {
25                     using (IsolatedStorageFileStream isoSteam = iso.OpenFile("notes.xml", FileMode.OpenOrCreate,FileAccess.ReadWrite))
26                     {
27                         XDocument xDoc = XDocument.Load(isoSteam);
28                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
29                         var child = new XElement("Note",
30                             new XElement("subject",note.Subject),
31                             new XElement("content",note.Content),
32                             new XElement("createtime",note.CreateTime),
33                             new XElement("endtime",note.EndTime));
34                         
35                         xDoc.Root.Add(child);
36                         xDoc.Save(isoSteam);
37                         System.Diagnostics.Debug.WriteLine( xDoc.ToString());
38                     }
39                 }
40                 else
41                 {
42                             IsolatedStorageFileStream stream = iso.CreateFile("notes.xml");
43                             StreamWriter writer = new StreamWriter(stream);
44                             serializer.Serialize(writer, noteCollection);
45                             writer.Close();
46                 }
47             }
48         }
49 
50         public NoteCollection Load()
51         {
52             IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
53             NoteCollection noteCollection = new NoteCollection();
54 
55             if (iso.FileExists("notes.xml"))
56             {
57                 IsolatedStorageFileStream stream = iso.OpenFile("notes.xml", FileMode.Open);
58                 StreamReader reader = new StreamReader(stream);
59 
60                 XmlSerializer ser = new XmlSerializer(typeof(NoteCollection));
61                 noteCollection = ser.Deserialize(reader) as NoteCollection;
62 
63                 reader.Close();
64             }
65             iso.Dispose();
66             return noteCollection;
67         }
68     }
69 
70     [XmlRoot("Notes")]
71     public class NoteCollection
72     {
73         [XmlArray("notes"), XmlArrayItem("note")]
74         public Note[] Notes { get; set; }
75     }
76 
77     [XmlRoot("note")]
78     public class Note
79     {
80         [XmlElement("subject")]
81         public string Subject { set; get; }
82 
83         [XmlElement("content")]
84         public string Content { set; get; }
85 
86         [XmlElement("createtime")]
87         public DateTime CreateTime { set; get; }
88 
89         [XmlElement("endtime")]
90         public DateTime EndTime { set; get; }
91     }

运行调试后,XML文件内容为:

 1 <notes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 2   <notes>
 3     <note>
 4       <content>Note1</content>
 5       <createtime>2010-01-01T00:00:00</createtime>
 6       <endtime>0001-01-01T00:00:00</endtime>
 7     </note>
 8     <note>
 9       <content>Note2</content>
10       <createtime>2012-01-01T00:00:00</createtime>
11       <endtime>0001-01-01T00:00:00</endtime>
12     </note>
13     <note>
14       <content>Write here...</content>
15       <createtime>2012-12-11T10:41:45.693+08:00</createtime>
16       <endtime>0001-01-01T00:00:00</endtime>
17     </note>
18   </notes>
19 </notes>

在这种情况下,使用xDoc.Root.Add(child)向XML中添加子节点的话,节点会被添加到notes第一个根节点下,这不是我想要的结果。

所以直接在判断如果XML文件不存在的时候就新生成XML文件,不使用序列化了。

使用Linq to xml方式向文件中添加数据

 1  public void AddToXml(Note note,NoteCollection noteCollection)
 2         {
 3             var child = new XElement("Note",
 4                             new XElement("subject", note.Subject),
 5                             new XElement("content", note.Content),
 6                             new XElement("createtime", note.CreateTime),
 7                             new XElement("endtime", note.EndTime));
 8 
 9             using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
10             {
11                 if (iso.FileExists("notes.xml"))
12                 {
13                     using (IsolatedStorageFileStream isoSteam = new IsolatedStorageFileStream("notes.xml", FileMode.OpenOrCreate, iso))
14                     {
15                         XDocument xDoc = XDocument.Load(isoSteam);
16                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
17                         xDoc.Root.Add(child);
18                         xDoc.Save(isoSteam);
19                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
20                     }
21                 }
22                 else
23                 {
24                     //using (IsolatedStorageFileStream isoStream = iso.CreateFile("notes.xml"))
25                     using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("notes.xml",FileMode.Create,iso))
26                     {                       
27                         var xDoc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), new XComment("this is notes list"), new XElement("notes", child));
28                         //StreamWriter fileWriter = new StreamWriter(isoStream);
29                         //xDoc.Save(fileWriter);
30                         xDoc.Save(isoStream);
31 
32 
33                     }
34                 }
35             }
36         }

调试这段代码的时候会报出一个异常:"Unhandled Exception: System.Xml.XmlEception: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 10, Position 11."

查阅资料后,发现问题的关键在于xDoc.Save(isoStream). XDocument的Save方法会自动为XML文件添加默认的声明。在向XML文件中调用Save方法保存就会又重复生成一个XML declaration。于是就会报出上面的异常。解决方法是只要把xDoc.Save(isoStream)去掉即可。

 1   public void AddToXml(Note note,NoteCollection noteCollection)
 2         {
 3             var child = new XElement("Note",
 4                             new XElement("subject", note.Subject),
 5                             new XElement("content", note.Content),
 6                             new XElement("createtime", note.CreateTime),
 7                             new XElement("endtime", note.EndTime));
 8 
 9             using (IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication())
10             {
11                 if (iso.FileExists("notes.xml"))
12                 {
13                     using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("notes.xml", FileMode.Open, iso))
14                     {
15                         XDocument xDoc = XDocument.Load(isoStream); 
16                         isoStream.SetLength(0); 
17                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
18                         xDoc.Root.Add(child);
19                         //xDoc.Element("notes").Add(child); 
20                         isoStream.Write(System.Text.Encoding.UTF8.GetBytes(xDoc.ToString()), 0, xDoc.ToString().Length);
21 
22                     }
23                 }
24                 else
25                 {
26                     using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("notes.xml",FileMode.Create,iso))
27                     {                       
28                         var xDoc = new XDocument(new XElement("notes", child));
29                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
30                         xDoc.Save(isoStream,SaveOptions.None);
31                     }
32                 }
33             }
34         }

写到这里,如果把代码改写成

1 XDocument xDoc = XDocument.Load(isoStream); 
2                         isoStream.SetLength(0); 
3                         System.Diagnostics.Debug.WriteLine(xDoc.ToString());
4                         xDoc.Root.Add(child);
5                         xDoc.Save(isoStream);

依然有效。所以根本原因应该是isoStream流还残有load时的数据,在新增时,save方法会把原来的数据再重复保存一遍。所以用isoStream.SetLength(0)清空原数据,再新增。

转载于:https://www.cnblogs.com/sevennight/archive/2012/12/12/UnexpectedXMLdeclaration.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值