XMLDocument:缺少根元素
本文关键字:元素 XMLDocument | 更新日期: 2023-09-27 18:33:02
我正在制定一个程序来管理我们公司的所有客户。我想使用 XML 文件来保存客户。所以我创建了一个XML文件(如果不存在(并用元素填充它。在这里你可以看到我是怎么做的:
string path = "C:''Users''Römel''Desktop''Save";
List<Kunde> kunde = new List<Kunde>();
private void Form1_Load(object sender, EventArgs e)
{
XmlDocument xdocument = new XmlDocument();
xdocument.Load(path + "''save.xml");
foreach (XmlNode xnode in xdocument.SelectNodes("Kundenverwaltung/Kunde"))
{
Kunde k = new Kunde();
k.KundenNr = xnode.SelectSingleNode("KundenNr").InnerText;
k.Nachname = xnode.SelectSingleNode("Nachname").InnerText;
k.Vorname = xnode.SelectSingleNode("Vorname").InnerText;
k.Adresse = xnode.SelectSingleNode("Adresse").InnerText;
k.Ort = xnode.SelectSingleNode("Ort").InnerText;
k.Telefon = xnode.SelectSingleNode("Telefon").InnerText;
k.Mail = xnode.SelectSingleNode("Mail").InnerText;
kunde.Add(k);
listViewKunden.Items.Add(k.Nachname + " " + k.Vorname);
}
}
private void btnAddCustomer_Click(object sender, EventArgs e)
{
if(!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
if (!File.Exists(path + "''save.xml"))
{
XmlTextWriter xwriter = new XmlTextWriter(path + "''save.xml", Encoding.UTF8);
xwriter.WriteStartElement("Kundenverwaltung");
xwriter.WriteEndElement();
xwriter.Close();
}
Kunde k = new Kunde();
k.KundenNr = txtKundenNr.Text;
k.Nachname = txtKundeNachname.Text;
k.Vorname = txtKundeVorname.Text;
k.Adresse = txtKundeAdresse.Text;
k.Ort = txtKundeOrt.Text;
k.Telefon = txtKundeTel.Text;
k.Mail = txtKundeMail.Text;
kunde.Add(k);
listViewKunden.Items.Add(k.Nachname + " " + k.Vorname);
txtKundenNr.Text = "";
txtKundeNachname.Text = "";
txtKundeVorname.Text = "";
txtKundeAdresse.Text = "";
txtKundeOrt.Text = "";
txtKundeTel.Text = "";
txtKundeMail.Text = "";
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load(path + "''save.xml");
XmlNode xnode = xdoc.SelectSingleNode("Kundenverwaltung");
xnode.RemoveAll();
foreach (Kunde k in kunde)
{
XmlNode xtop = xdoc.CreateElement("Kunde");
XmlNode xkundennr = xdoc.CreateElement("KundenNr");
XmlNode xnachname = xdoc.CreateElement("Nachname");
XmlNode xvorname = xdoc.CreateElement("Vorname");
XmlNode xadresse = xdoc.CreateElement("Adresse");
XmlNode xort = xdoc.CreateElement("Ort");
XmlNode xtel = xdoc.CreateElement("Telefon");
XmlNode xmail = xdoc.CreateElement("Mail");
xkundennr.InnerText = k.KundenNr;
xnachname.InnerText = k.Vorname;
xvorname.InnerText = k.Nachname;
xadresse.InnerText = k.Adresse;
xort.InnerText = k.Ort;
xtel.InnerText = k.Telefon;
xmail.InnerText = k.Mail;
xtop.AppendChild(xkundennr);
xtop.AppendChild(xnachname);
xtop.AppendChild(xvorname);
xtop.AppendChild(xadresse);
xtop.AppendChild(xort);
xtop.AppendChild(xtel);
xtop.AppendChild(xmail);
xdoc.DocumentElement.AppendChild(xtop);
}
xdoc.Save(path + "''save.xml");
e.Cancel = false;
this.Close();
}
对于KundenNr
、Nachname
等。我在文件的末尾创建了一些类。我希望它不是太多的代码。
首先:我不能使用右上角的常规"X"按钮,因为如果我点击它就没有反应。所以我创建了一个Exit
按钮。
第二:每次我点击退出按钮离开程序时,这一行都会出现错误:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
xdoc.Load(path + "''save.xml");
}
出现"缺少根元素"。有人知道这个错误并且可以给我一个提示吗?
编辑:对于btnExit_Click
,我使用此代码:
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
XmlDocument 强制实施有效的 XML 文档必须有一个根元素的规则。
不确定您的代码到底在做什么,但我怀疑它正在创建可能如下所示的 XML:
<Kunde ... />
<Kunde ... />
<Kunde ... />
<Kunde ... />
<Kunde ... />
。它需要看起来像这样的地方:
<Kunden>
<Kunde ... />
<Kunde ... />
<Kunde ... />
<Kunde ... />
<Kunde ... />
</Kunden>
换句话说,您需要创建一个且只有一个元素直接添加到文档中(它将成为您的根元素(,并在其中添加所有其他元素。
您可以从一件事加载XmlDocument
并将其保存到另一件事。它是内存中的表示形式。鉴于您正在执行完全覆盖以尝试处理这是不必要的,这比创建根节点要多得多。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml("<Kundenverwaltung"></Kundenverwaltung>"); // You might want to put any xml directives, default attributes, etc. in here.
XmlNode xnode = xdoc.SelectSingleNode("Kundenverwaltung");
foreach (Kunde k in kunde)
{
//Create and add each Kunde node as before
}
xdoc.Save(path + "''save.xml");
e.Cancel = false;
}
所以现在你要做的就是删除你现在拥有的达夫。不过,我看到一些潜在的问题正在向你袭来。无论是否有任何更改,文件都在写入。 XmlDocument
将所有内容保存在内存中,因此此解决方案仅适用于较小的文档。如果像这里的情况一样(在某些时候怀疑有错误(,你的文件就会被塞满,所有数据都会丢失。您可能需要考虑上述内容,但要保存到临时文档中。然后尝试加载或验证它,如果它返回正常,则重命名它以保存,否则报告问题。这样,至少只有这些"会话"更改丢失了。
一般来说,我从不调用XmlDoument.Load("Fred.xml"(或保存。我做类似的事情。
XmlDocument doc = new XmlDocument();
using(FileStream rfs = new FileStream("OldFred.xml",FileMode.Open,FileAccess.Read))
{
doc.Load(rfs);
//do my reading stuff)
}
using(FileStream wfs = new FileStream("NewFred.xml",FileMode.Create,FileAccess.Write))
{
//do my Writing stuff
doc.Save(wfs);
}
使用FileStream的优点是,如果Oldfred不存在,或者您没有对NewFred所在的文件夹的写入权限,您将立即失败。这是我们在处理文件系统的并发和多用户访问时养成的习惯。这意味着XmlDocument读写代码永远不必处理文件系统,处理FileStreams的代码会处理这个问题。