mohammad haris
mohammad haris

Reputation: 145

Edit XML file in Windows Store app

I am making an app in windows store and having a problem in writing xml in created xml file. I have followed this Editing XML file in Windows Store App but it didn't work for me.

I want this xml to be wrote in my xml file on button click.

Any alternate way for this stuff..

<drink>
    <drinkImage>ck.png</drinkImage>
    <drinkTitle>COKE</drinkTitle>
    <drinkDescription>(1793-1844)</drinkDescription>
  </drink>

my current file is this:

   <?xml version="1.0" encoding="utf-8" ?>
    <drinks>
      <drink>
        <drinkImage>pepsi.png</drinkImage>
        <drinkTitle>PEPSI</drinkTitle>
        <drinkDescription>(1793-1844)</drinkDescription>
      </drink>
**<here I Want above xml on button click>**
    </drinks>

Here is what I have tried:

namespace DrinksApp
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class coke : Page
    {
        public coke()
        {
            this.InitializeComponent();

        }
        XmlDocument dom = new XmlDocument();


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.Frame.Navigate(typeof(softdrinks));
        }

        private async void Button_Click_1(object sender, RoutedEventArgs e)
        {
               XDocument xmlDoc = XDocument.Load("favourite//fav.xml");
        xmlDoc.Root.Add(new XElement("drink",
                    new XAttribute("drinkImage","ck.png"),
                    new XAttribute("drinkTitle","PEPSI"),
                    new XAttribute("drinkDescription","NONE")

                ));



xmlDoc.Save(xmlDoc); **//This isn't working in windows store ..**
            }



        }




    }
}

I already have an xml file as mentioned above:

Upvotes: 7

Views: 454

Answers (3)

t.ouvre
t.ouvre

Reputation: 3001

You can't save your XML document here. All files from app package are read-only. You have to save your xml document into localState :

    public async Task DoJobAsync()
    {
        XDocument xmlDoc = XDocument.Load("favourite//fav.xml");
        xmlDoc.Root.Add(new XElement("drink",
                    new XAttribute("drinkImage", "ck.png"),
                    new XAttribute("drinkTitle", "PEPSI"),
                    new XAttribute("drinkDescription", "NONE")

                ));
        using (var stream = await (await ApplicationData.Current.LocalFolder.CreateFileAsync("fav.xml")).OpenAsync(FileAccessMode.ReadWrite))
        {
            xmlDoc.Save(stream.AsStreamForWrite());
        }
    }

Upvotes: 3

Travis Boatman
Travis Boatman

Reputation: 2282

Wrote this in a console app, but it should still work for Windows Store App.

      XDocument xdoc = XDocument.Load("fa.xml");

        xdoc.Root.Add(new XElement("drink",
            new XElement("drinkImage", "Img.png"),
            new XElement("drinkTitle", "NewDrink"),
            new XElement("drinkDescription", "HelloWorld")));

        xdoc.Save("fa.xml");

Output:

<?xml version="1.0" encoding="utf-8"?>
<drinks>
  <drink>
    <drinkImage>pepsi.png</drinkImage>
    <drinkTitle>PEPSI</drinkTitle>
    <drinkDescription>(1793-1844)</drinkDescription>
  </drink>
  <drink>
    <drinkImage>Img.png</drinkImage>
    <drinkTitle>NewDrink</drinkTitle>
    <drinkDescription>HelloWorld</drinkDescription>
  </drink>
</drinks>

Your original code is very close to what you wanted. You used 'XAttribute' rather than 'XElement'. This isn't a problem but the output would have looked like this...

<drink drinkImage="ck.png" drinkTitle="PEPSI" drinkDescription="NONE" />

Your actual problem was saving. XDoucment.Save accepts a stream, text writer, xml writer, or string. In this example I used the string path. See more here: https://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument(v=vs.110).aspx

EDIT: Try using a filestream:

var xmlFile = await StorageFile.GetFileFromPathAsync("fav.xml");
using (var fileStream = await xmlFile.OpenStreamForWriteAsync())
{
   xdoc.Save(fileStream);
}

Upvotes: 2

har07
har07

Reputation: 89325

This is possibly the correct way (didn't test in windows store project). Pay attention to which element added to which parent element and what inner text being assigned to which element, that is where your original codes incorrectly do (I appreciate the effort though) :

var existingRoot = dom.DocumentElement;

var newElement = dom.CreateElement("drink");
existingRoot.AppendChild(newElement);

var drinkImageElement = dom.CreateElement("drinkImage");
drinkImageElement.InnerText = "ck.png";
newElement.AppendChild(drinkImageElement);

var drinkTitleElement = dom.CreateElement("drinkTitle");
drinkTitleElement.InnerText = "COKE";
newElement.AppendChild(drinkTitleElement);

var drinkDescriptionElement = dom.CreateElement("drinkDescription");
drinkDescriptionElement.InnerText = "Nothing";
newElement.AppendChild(drinkDescriptionElement);

Here is a link to online demo (console based apps) : https://dotnetfiddle.net/oElYWJ

output :

<drinks>
  <drink>
    <drinkImage>pepsi.png</drinkImage>
    <drinkTitle>PEPSI</drinkTitle>
    <drinkDescription>(1793-1844)</drinkDescription>
  </drink>
  <drink>
    <drinkImage>ck.png</drinkImage>
    <drinkTitle>COKE</drinkTitle>
    <drinkDescription>Nothing</drinkDescription>
  </drink>
</drinks>

Upvotes: 4

Related Questions