2013-06-30 1 views
0

J'ai un formulaire avec les boutons load, save, add et navigation, qui manipule un fichier XML.Format XML non valide après la suppression du noeud

est ici la structure et le contenu du fichier XML:

<?xml version="1.0" encoding="utf-8"?> 
<BookList> 
    <Book> 
    <Title>Song of myself</Title> 
    <Author>Walt Whitman</Author> 
    <isbn>234-0232</isbn> 
    <Year>1999</Year> 
    <Editure>Some editure</Editure> 
    </Book> 
    <Book> 
    <Title>Richard III</Title> 
    <Author>William Shakespeare</Author> 
    <isbn>234-23432</isbn> 
    <Year>2001</Year> 
    <Editure>Some other editure</Editure> 
    </Book> 
</BookList> 

Et voici le code pour le bouton de suppression (que j'ai des problèmes avec):

private void button8_Click(object sender, EventArgs e) 
{ 
    XmlNodeList nodes = xmlDoc.SelectNodes("//BookList/Book"); 

    foreach (XmlNode item in nodes) 
    {      
     string ISBN = item["isbn"].InnerText; 

     if (ISBN == textBox3.Text) 
     { 
      try 
      { 
       item.ParentNode.RemoveChild(item);       
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      }        
     }      
    } 

    saveFile(); 

    xpatNav = moveToFirstBook(xpatNav); 
    List<String> values = this.retrieveCurrentValues(xpatNav); 
    loadTextBoxes(values);     
} 

Le formulaire a un texte ISBN champ. Le code itère à travers les nœuds XML et, si l'ISBN du nœud actuel est le même que l'ISBN du nœud du formulaire, il le supprime (eh bien, il devrait le faire). Ensuite, le fichier est enregistré et le formulaire se positionne sur le premier nœud (les trois derniers nœuds).

Cependant, disons que nous nous positionnons sur le dernier livre - quand j'appuie sur le bouton de suppression, tout ce que je reçois est un fichier xml foiré, qui ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?> 
<BookList> 
    <Book> 
    <Title>Song of myself</Title> 
    <Author>Walt Whitman</Author> 
    <isbn>234-0232</isbn> 
    <Year>1999</Year> 
    <Editure>Some editure</Editure> 
    </Book> 
    </BookList> 
    <Title>Richard III</Title> 
    <Author>William Shakespeare</Author> 
    <isbn>234-23432</isbn> 
    <Year>2001</Year> 
    <Editure>Some other editure</Editure> 
    </Book> 
</BookList> 

J'ai essayé une multitude de façons de l'accomplir, mais je ne comprends tout simplement pas. Ok, donc j'ai changé un peu le code, à la suggestion de Jens Erat. Le code du bouton de suppression ressemble (changement mineur si):

private void button8_Click(object sender, EventArgs e) 
     { 
      XmlNodeList node = xmlDoc.SelectNodes("//ListaCarti/Carte[isbn='" + textBox3.Text + "']"); 

      try 
      { 
       node.Item(0).ParentNode.RemoveChild(node.Item(0)); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 

      saveFile(); 

      xpatNav = moveToFirstBook(xpatNav); 
      List<String> values = this.retrieveCurrentValues(xpatNav); 
      loadTextBoxes(values); 
     } 

Voici le code pour enregistrer le fichier:

private void saveFile() 
     { 
      fs = new FileStream(this.openedXml, FileMode.Open, FileAccess.Write, FileShare.Write); 
      xmlDoc.Save(fs); 
      fs.Close(); 
     } 

où this.openedXml c'est le chemin vers le fichier XML ouvert.

Et voici le code pour le bouton de chargement:

public void loadXml() 
     { 
      if (XMLloaded) 
      {     
       try 
       { 
        fs = new FileStream(this.openedXml, FileMode.Open, FileAccess.Read); 
        xmlDoc.Load(fs); 
        fs.Close(); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 

       xpatNav = xmlDoc.CreateNavigator(); 

       XPathNavigator xnav = xpatNav; 

       countNodes(xnav); 

       // we load the first value into the form 
       if (this.nodesNumber > 0) // if the XML it's not empty 
       {  
        xnav = moveToFirstBook(xnav 


        //this retrieve the values for current title, author, isbn, editure 
        List<string> values = retrieveCurrentValues(xnav);     

        loadTextBoxes(values); 
       } 
      } 
     } 

Je pense que cela semble un peu désordonné, pourrait alors voici un problème.

+1

Votre 2ème exemple est un code XML non valide, êtes-vous sûr que cela provient d'un document XmlDocument? Si oui, assurez-vous de poster le code Load & Save. On dirait que vous faites un remplacement partiel du fichier. –

+1

'SelectNodes' semble utiliser des expressions XPath; Si c'est le cas, vous pouvez enregistrer la boucle et utiliser '// BookList/Book [isbn = '234-23432']' (construit à partir de la variable ISBN, bien sûr, mais vous ne pouvez pas vous aider avec votre problème.) –

+0

semble être le fichier est ouvert pour Append, Rewinded, puis écrit le flux ... –

Répondre

1

Modifiez votre méthode Save(). Celui en cours remplace seulement le début du fichier mais ne supprime pas l'ancien contenu (plus long).

private void saveFile() 
    { 
     //fs = new FileStream(this.openedXml, FileMode.Open, FileAccess.Write, FileShare.Write); 
     fs = new FileStream(this.openedXml, FileMode.Create); 
     xmlDoc.Save(fs); 
     fs.Close(); 
    } 
+0

Merci. – user2536272