0

I want to set the attributes pro_id and prod_xml to empty whenever I press on unfavorite icon from the application bar. After all, the values were set to empty, however it also added one more root element to the XML file like this:

<?xml version="1.0" encoding="utf-8"?>
<favorites>
  <favorite id="1" pro_id="" prod_xml="" />
  <favorite id="2" pro_id="" prod_xml="" />
  <favorite id="3" pro_id="" prod_xml="" />
  <favorite id="4" pro_id="" prod_xml="" />
</favorites> />
</favorites>

This is how I create xml file from blank (no error):

public void createFavXML()
{
    // Get the local folder.
    System.IO.IsolatedStorage.IsolatedStorageFile local =
        System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();

    // Create a new folder named DataFolder.
    if (!local.DirectoryExists("Favorite"))
            local.CreateDirectory("Favorite");
 //       local.DeleteFile("Favorite\\favorite.xml");
        if (!local.FileExists("Favorite\\favorite.xml"))
        {
            // Create a new file named DataFile.txt.
            using (var isoFileStream = 
new System.IO.IsolatedStorage.IsolatedStorageFileStream("Favorite\\Favorite.xml", System.IO.FileMode.OpenOrCreate, local))
        {

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            using (XmlWriter writer = XmlWriter.Create(isoFileStream, settings))
            {
                writer.WriteStartElement("favorites", "");
                // favorite id 1
                writer.WriteStartElement("favorite", "");
                // attribute id
                writer.WriteStartAttribute("id", "");
                writer.WriteString("1");
                writer.WriteEndAttribute();
                // attribute product id
                writer.WriteStartAttribute("pro_id", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                // attribute prod_xml
                writer.WriteStartAttribute("prod_xml", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                writer.WriteEndElement();

                // favorite id 2
                writer.WriteStartElement("favorite", "");
                // attribute id
                writer.WriteStartAttribute("id", "");
                writer.WriteString("2");
                writer.WriteEndAttribute();
                // attribute product id
                writer.WriteStartAttribute("pro_id", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                // attribute prod_xml
                writer.WriteStartAttribute("prod_xml", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                writer.WriteEndElement();

                // favorite id 3
                writer.WriteStartElement("favorite", "");
                // attribute id
                writer.WriteStartAttribute("id", "");
                writer.WriteString("3");
                writer.WriteEndAttribute();
                // attribute product id
                writer.WriteStartAttribute("pro_id", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                // attribute prod_xml
                writer.WriteStartAttribute("prod_xml", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                writer.WriteEndElement();

                // favorite id 4
                writer.WriteStartElement("favorite", "");
                // attribute id
                writer.WriteStartAttribute("id", "");
                writer.WriteString("4");
                writer.WriteEndAttribute();
                // attribute product id
                writer.WriteStartAttribute("pro_id", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                // attribute prod_xml
                writer.WriteStartAttribute("prod_xml", "");
                writer.WriteString("");
                writer.WriteEndAttribute();
                writer.WriteEndElement();



                // Ends the document
                writer.WriteEndElement();

                writer.Flush();
            }


        }
    }

}

This is where I write data to xml file for the specific id passed to it (working fine)

   public void writeTOFavxml(string favId,string pro_id,string prod_xml)
    {

        var storage = IsolatedStorageFile.GetUserStoreForApplication();
        fileName = "Favorite\\Favorite.xml";
        using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
        {

                   XDocument doc = XDocument.Load(isoStream);
                    foreach (var item in (from item in doc.Descendants("favorite")
                                     where item.Attribute("id").Value.Equals(favId)
                                     select item).ToList())
                    {

                        item.Attribute("pro_id").SetValue(pro_id);
                        item.Attribute("prod_xml").SetValue(prod_xml);

                    }                  
                    //First way
                    isoStream.Position = 0;
                    doc.Save(isoStream);                  
                }

    }

After the attributes prod_id and prod_xml have data, I want to be able to set it to be empty again for the specific id that pass to UnwriteXML() method (Problem is here)

public void UnwriteXML(string pro_id)
{
    var storage = IsolatedStorageFile.GetUserStoreForApplication();
    fileName = "Favorite\\Favorite.xml";
    XDocument docx = null;
    using (IsolatedStorageFileStream isoStreamx = new IsolatedStorageFileStream(fileName, FileMode.Open, storage))
    {
        docx = XDocument.Load(isoStreamx);
        foreach (var item in (from item in docx.Descendants("favorite")
                                      where item.Attribute("pro_id").Value.Equals(pro_id)
                                      select item).ToList())
        {
            item.Attribute("pro_id").SetValue("");
            item.Attribute("prod_xml").SetValue("");
        }

        //First way
        isoStreamx.Position = 0;
        docx.Save(isoStreamx);
    }  
}

I followed exactly the same steps as in the question from here updating an existing xml file in Windows Phone by setting isoStream to position 0, because I think he has the same problem as me, but the problem still remains.

Community
  • 1
  • 1
Houy Narun
  • 1,557
  • 5
  • 37
  • 86
  • 1
    Isn't it that you try to overwrite the old xml but since the new one is shorter than the original one you see leftovers at the end of the stream? – Pawel Sep 29 '14 at 06:38
  • @HouyNarun How about implementing the 2nd way? – har07 Sep 29 '14 at 06:49
  • @har07 from above link I followed the second way is "save XML document in the newly opened stream." `using (var stream = storage.OpenFile(fileName, FileMode.Open, FileAccess.Write)) { doc.Save(stream); }` I've tried both way, but still the same error. – Houy Narun Sep 29 '14 at 07:04
  • @Pawel I'm sure I'm not creating new xml overwrite old one. Because as I debug it at UnwriteXML() method and use ISETool.exe to download isolated storage contents, I see in xml file that only one specific id that passed to UnwriteXML() was cleared to be empty, other attributes of `pro_id` and `prod_xml` in other favorite elements still have the same value. Therefore, I think it updated rather than creating new xml. – Houy Narun Sep 29 '14 at 09:47
  • @HouyNarun - you are writing to a stream you read from so it looks to me you are overwriting the old xml. You can easily verify this by creating a new stream for the modified document and check if the contents is mangled - I am pretty sure it won't be because the new stream wont have any old data. – Pawel Sep 29 '14 at 16:49
  • @Pawel please check my edited question. I could able to create a blank xml file, I could able to write some data for specific id in xml file, however, I met problem when trying to empty the xml after it has data. If I only create it, add data to attributes pro_id and prod_xml and read it works fine, but if I try to empty it, it will create an extra element like above and show error, then I could not read again. – Houy Narun Sep 30 '14 at 01:48

1 Answers1

0

you should set your stream length, this will fix the issue

stream.SetLength(xdoc.ToString().Length);
Mahender
  • 5,554
  • 7
  • 38
  • 54