簡體   English   中英

XMLDocument:根元素丟失

[英]XMLDocument: Root element is missing

我正在制定一個程序來管理我們公司中的所有客戶。 我想使用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();
}

對於KundenNrNachname等我在文件的結尾創建了一些類。 我希望它不是太多的代碼。

第一:我不能使用右上角的常規“ 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;
}

因此,現在您要做的就是刪除現有的duff。 不過,我看到了一些潛在的問題。 無論是否進行任何更改,都將寫入文件。 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的代碼則負責這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM