Reputation: 397
Title says it all really. I've been stuck on this one for days and would appreciate some help. I've a main page and a settings page when the main page loads first time it tests for settings.xml in local folder and copies it if not found. Then when the user opens settings page it's supposed to load details from local folder allowing the user to edit before saving them back to the local folder from OnNavigatedFrom event.
Code to load from installation folder to local folder
// Has the file been copied already?
bool blFileExist = false;
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync("settings.xml");
// No exception means it exists
blFileExist = true;
btnSettings.Foreground = new SolidColorBrush(Windows.UI.Colors.White);
}
catch (System.IO.FileNotFoundException)
{
// The file obviously doesn't exist
blFileExist = false;
btnSettings.Foreground = new SolidColorBrush(Windows.UI.Colors.Red);
}
catch (Exception)
{
}
if (!blFileExist)
{
try
{
// Cant await inside catch, but this works anyway
StorageFile stopfile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("settings.xml");
await stopfile.CopyAsync(ApplicationData.Current.LocalFolder);
}
catch (System.IO.FileNotFoundException)
{
}
catch (Exception)
{
}
}
Code to load and save settings page
private void loadSettings()
{
try
{
doc = XElement.Load("settings.xml");
nAIPlayers = int.Parse(doc.Element("ai_players").Value);
strCardBack = doc.Element("back").Value;
comboBoxAIPlayers.SelectedIndex = nAIPlayers - 1;
}
catch (System.IO.FileNotFoundException)
{
}
catch (Exception ex)
{
}
}
private async void saveSettings()
{
//try
//{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("settings.xml");
using (Stream fileStream = await file.OpenStreamForWriteAsync())
{
doc.SetElementValue("ai_players", nAIPlayers);
doc.SetElementValue("back", "Back_0");
doc.Save(fileStream);
}
/*}
catch (System.IO.FileNotFoundException)
{
}
catch (Exception ex)
{
}*/
}
I think the problem is I'm accessing the local file to save it and the installation file to load it. The result is no matter what I save it always reads the values in the original settings.xml
How do I load this from the local folder?
doc = XElement.Load("settings.xml");
Update
On the first iteration the code runs fine and the settings page code opens as it should. It's only after leaving the settings page and running saveSettings() method that it fails and throws an error when reloading the settings page and running loadSettings().
System.Xml.XmlException: Data at the root level is invalid. Line 5, position 12
Upvotes: 0
Views: 3187
Reputation: 29792
You are doing it wrong because you are using XElement.Load(string) where string stands for URI, which in this case should be:
The Uri parameter must be a file system relative or absolute path.
and with that you will have a problem in UWP as normally you don't have the permission. It also won't work here with URIs like: "ms-appdata:///settings.xml"
.
Probably you can read a path to your LocalFolder and use it (may work, though haven't tested it), but much easier is to load the content from stream (or read string from file and then load XML from that string), for example like this:
var file = await ApplicationData.Current.LocalFolder.GetFileAsync("settings.xml");
using(var stream = await file.OpenStreamForReadAsync())
{
var doc = XElement.Load(stream);
// ...
}
Note also that there are other classes like XDocument or XmlDocument where you can load and manage you xml file. Everything depends on your needs.
Upvotes: 2