Introduction ; Part 1

-------------------------------------------------------------------------------

In my Previous post I took a simple wiki format and parsed and converted to XML format. But the output is displayed on a text box. Displaying XML output on a text box may not be a good idea always. In this blog post I am going to write the output to a file. Here is the interesting part, on windows phone seven we are not allowed to access file system, file structure, instead of that we are limited to something called IsolatedStorage.

 

What is this IsolatedStorage?

Imagine you are apparated four our concrete jungles to an island. Where do you store your fish?

Moving from whole file structure access of Desktop and windows mobile world to IsolatedStorage is similar. Here we own an island of storage, where nobody enters, at the same time we can not cross the island.

 

Where to Begin?

IslatedStorage is already famous in Silverlight for Desktop. Everything supported in System.IsolatedStorage name space in Silverlight Desktop is also available in windows phone 7, except IsolatedStorageFile.GetUserStoreForSite() (reference), this method is not going to restrict any scenarios for window sphone 7, we can happyly live without this one method.

 

Silverlight Desktop has good documentation for IsolatedStorage @  here.  Read this document, keep this as reference, follow the example there to get a good grip over IsolatedStorage namespace.

 

WikiToXMLIsolatedStorage

Let me show the modified method from previous blog post to write xml output to a file and store it in Application's IsolatedStorage space.

 

 private void ConvertWikiToXML()

        {

            ///

            /// Level to represent where we are at current moment in the tree.

            ///

            int level = 0;

            int previousLevel = 0;

            string outputFileName = "out.xml";

 

            // Sample Input.

            string input =

                    @"==Heading==

                    This is Heading

                    ===Sub Heading One===

                    Text At Level Two:One

                    ====Sub Sub Heading====

                    Text At Level Three

                    ===Sub Heading Two===

                    Text At Level Two:Two

 

                    ";

            try

            {

               

                using (var store = IsolatedStorageFile.GetUserStoreForApplication())

                {

 

                    // if the output file already present, then delete it.

                    if (store.FileExists(outputFileName))

                    {

                        store.DeleteFile(outputFileName);

                    }

 

                    // create and open the output file.

                    IsolatedStorageFileStream isoStream = store.OpenFile(outputFileName, FileMode.CreateNew, FileAccess.Write);

                    //Create an XML Writer.

                    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();

                    XmlWriter xmlWriter = XmlWriter.Create(isoStream, xmlWriterSettings);

 

                    //Start Reading input.

                    byte[] byteArray = Encoding.UTF8.GetBytes(input);

                    MemoryStream memoryStream = new MemoryStream(byteArray);

                    StreamReader streamReader = new StreamReader(memoryStream);

 

                    // Write Start of XML Document.

                    xmlWriter.WriteStartDocument();

                    xmlWriter.WriteWhitespace(Environment.NewLine); // Write a new line for formatting.

                    // Write root element start.

                    xmlWriter.WriteStartElement("root");

                    xmlWriter.WriteWhitespace(Environment.NewLine); // Write a new line for formatting.

                    do

                    {

                        string line = streamReader.ReadLine();

                        if (line == null) break; // end of input stream.

                        if (line == string.Empty) continue; // empty line.

                        line = line.Trim(); // Actually wiki won't trim initial white space , but let us do it for time being.

 

                        if (IsNewLevelStartTag(line))

                        {

                            previousLevel = level;

                            level = GetLevel(line);

                            for (int i = 0; i <= previousLevel - level; i++)

                            {

                                // Write end element, we are exiting a sub level to it higher level.

                                xmlWriter.WriteEndElement();

                                xmlWriter.WriteWhitespace(Environment.NewLine); // Write a new line for formatting.

 

                            }

                            xmlWriter.WriteStartElement("Level" + level.ToString());

                            char[] trimChar = new char[1];

                            trimChar[0] = '=';

                            xmlWriter.WriteAttributeString("name", line.Trim(trimChar));

                        }

                        else

                        {

                            // Write the content.

                            xmlWriter.WriteString(line);

                        }

 

 

                        xmlWriter.WriteWhitespace(Environment.NewLine); // Write a new line for formatting.

 

                    } while (true);

 

                    // Write root element end.

                    xmlWriter.WriteEndElement();

                    // Write End of XML Document.

                    xmlWriter.WriteEndDocument();

 

                    // Don't forget to close the XML, otherwise you won't see your xml flushed.

                    xmlWriter.Close();

                    // Close the IsolatedStorageStream.

                    isoStream.Close();

                    // Close the StreamReader

                    streamReader.Close();

 

                    //Write the output to text box.

                    // open a read only isoStream of our output.

                    isoStream = store.OpenFile(outputFileName, FileMode.Open, FileAccess.Read);

                    // We can read isoStream in chunks, or Create a SreamReader and ReadToEnd in one shot.

                    StreamReader outputStreamReader = new StreamReader(isoStream);

                    textBox1.Text = outputStreamReader.ReadToEnd(); // Display on text box, just like that.

                }

            }

            catch (IsolatedStorageException isoException)

            {

                textBox1.Text = "Isolated Storage Exception Occurred" + isoException.ToString();

            }

            catch (Exception e)

            {

                textBox1.Text = e.Message;

            }

        }

 

  

 

        private int GetLevel(string line)

        {

            int level = 0;

            char[] lineChars = line.ToCharArray();

            for (int i = 0; i < lineChars.Length; i++)

            {

                if (lineChars[i] == '=')

                {

                    level++;

                }

                else

                {

                    break;

                }

            }

            return level;

        }

 

        private bool IsNewLevelStartTag(string line)

        {

            if (line.StartsWith("==") && line.EndsWith("=="))

            {

                return true;

            }

            return false;

        }

 

Explanation:

All our IsolatedStorageFile operations start with getting handle (of type IsolatedStorageFile) to the store by calling  IsolatedStorageFile.GetUserStoreForApplication(); It is adviced to close this as soon as finish over operations. This can be easily achieved by writing all the block of code in using{ } as show above.

 

IsolatedStorageFile class provides a cute list of methods with self explanatory names. In the above program the highlited parts show how IsolatedStorage can be used to write and read a file. We used FileExists(), DeleteFile(), OpenFile(), Close() methods to accomplish the task.

 

Note: As emulator in current release is not going to persist data all data written to IsolatedStorage will be wiped once emulator is closed and reopened.

 

====

Download the solution from here