C# XMLDocument:缺少根元素
我正在制定一个计划来管理我们公司的所有客户。我想使用一个XML文件来保存客户。因此,我创建了一个XML文件(如果不存在的话)并用元素填充它。在这里你可以看到我是如何做到的:C# XMLDocument:缺少根元素,c#,xml,C#,Xml,我正在制定一个计划来管理我们公司的所有客户。我想使用一个XML文件来保存客户。因此,我创建了一个XML文件(如果不存在的话)并用元素填充它。在这里你可以看到我是如何做到的: string path = "C:\\Users\\Römel\\Desktop\\Save"; List<Kunde> kunde = new List<Kunde>(); private void Form1_Load(object sender, EventArgs e) { XmlD
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();
}
“根元素丢失”出现。有人知道这个错误并能给我一个提示吗
编辑:对于btnExit\u,单击I使用此代码:
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;
}
使用FileStream的优点是,如果Oldfred不存在,或者您没有对NewFred所在的文件夹的写访问权限,您会立即失败。这是我们在处理对文件系统的并发和多用户访问时养成的习惯。这意味着XmlDocument的读写代码永远不必处理文件系统,处理文件流的代码会处理这一点。为什么在表单关闭时要加载数据?你不想保存它吗?是的,但我必须先加载它。在那之后,我会保存它。请参见表单1\u FormClosing
:)末尾的.Save
),或者我完全错了吗?啊,我在看你的代码片段,它显示了异常的位置,而不是完整的代码。加载时,save.xml
中有什么内容?用记事本加载xml,我怀疑在某个时候文件已被填满,而您没有根节点。在加载文件、擦除所有子文件并重写它们时,为什么不每次创建一个新文件呢?Mh,save.xml
是空的。所以每次我用file.create创建一个新文件时,我必须编辑xml并手动添加一个根元素?有没有办法在没有任何错误的情况下快速地包装根元素?当然,您可以通过编程来完成。只是不确定您所编写的代码是否符合要求。基本上,当您创建一个新的XmlDocument时,您需要创建一个XmlElement作为您的“根”,并将其添加到XmlDocument中。然后,在创建内容的XmlElements时,将它们添加到“根”XmlElement中(或其下),而不是直接添加到XmlDocument本身。顺便说一句我开始使用XmlDocument,但最终改用XDocument(LINQXML)。如果你正在为.NET 4或更高版本开发,你也应该考虑切换——写起来要容易得多。好的,我想我要写另一个程序来测试它,然后我会用它:谢谢YouPS,如果你想用XMLReald/XMLMeX处理大文档,你可以有两个文件。如果我是你,我会考虑使用FielestRAMs而不是Load并用字符串保存,这样你就可以知道文件系统问题,而不是仅仅将字符串传递给XMLDoice。加载、保存和交叉手指。使用FileStream
是否完全是另一种方式?我必须告诉你:你是老板!非常感谢!它工作得很好!一个问题:使用XmlDocument
,最多200个客户是否太多了?不应该这么认为。特别是考虑到它是一次点击加载和一次保存。只需注意文档的大小。FileStream只是一个小小的改进。例如,除非你已经阻止了它,否则如果你的两个应用程序同时运行并关闭,会发生什么?
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 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);
}