Start Here: wikiToXML: Introduction
Let us covert a simple wiki formatting to an XML file.
Input String
==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
Output XML
<?xml version="1.0" encoding="utf-8"?><root> <Level2 name="Heading"> This is Heading <Level3 name="Sub Heading One"> Text At Level Two:One <Level4 name="Sub Sub Heading"> Text At Level Three </Level4> </Level3> <Level3 name="Sub Heading Two"> Text At Level Two:Two </Level3> </Level2></root>
Here are the methods to do above task:
private void ConvertWikiToXML() { /// /// Level to represent where we are at current moment in the tree. /// int level = 0; int previousLevel = 0;
// 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 { //Create an XML Writer. StringBuilder stringBuilder = new StringBuilder(); XmlWriterSettings xmlWriterSettings = new XmlWriterSettings(); XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, 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! xmlWriter.Close(); textBox1.Text = stringBuilder.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
Basically, we use provided XmlWriter class's Create() method to create an XmlWriter instance and then use WriteStartDocument(), WriteWhitespace(), WriteStartElement(), WriteEndElement() WriteAttributeString(), WriteString(), WriteEndDocument(), Close() methods of XmlWriter class to do the task. To test we can create a button/text box in the solution and try out. For an idea see below screen shot.
====
Update: Attachment is added, download the zip file from here.
===
Update: Next In series WikiToXML2: Writing output file to IsolatedStorage