I have created a small project and want to implement few things in it.
but since i m new to C# and XML i m finding it difficult to proceed.
These are things which i want in my project....
- The use of a background thread for the process of loading the XML data, possibly with a progress bar to let the user know that the application is actively doing something.
- NodeType is of enumarated type XmlNodeType, yet the values are compared as strings.What should be there instead of strings?How to use enumerated data types?
- The while(flag) execution control structure can potentially lead to
infinite loop, the algorithm could be better formulated, with a more
explicit (i.e. visible/understandable for the developer) loop
condition.Ho wto use for loop here?
- In treeView1_AfterSelect, the text parsing code depends on the textual
representation for a node in the tree view, which can be changed at any
time and break the entire logic of list display. This strong dependency
between the tree view and the list display should be eliminated by
binding nodes in the treeview to nodes of the XML document, so that the
raw Xml data can be used to display text in the list.What should i write here?
- Improve structure of code by placing related business logic in separate class while keeping frontend class free from business logic as far as possible. It is recommended to use a class for xml related logic taking xml file "uri" as initializer. The use of a Model-View architecture is recommended, to achieve separation of concerns. How to proceed in this case?
- Improve display of node attributes such that only node name is added to tree and attributes of clicked node appear in GUI controls on right hand side of form.
using System.IO;
using System.ComponentModel;
using System.Threading;
using System.Xml;
using System.Windows.Forms;
namespace LoadXMLtreeDisplay
{
public partial class TreeDisplay : Form
{
public string Filename
{ get { return filename; } }
protected string filename;
//Declaring constructor of the Class
public TreeDisplay()
{
InitializeComponent();
this.Text = "Tree View of XML File";//Form Title.
}//TreeDisplay Constructor
private void initiatingTree(string nameofFile)
{
try
{
//Create XML document & load the XML file.
//xmlDocument.Load(nameofFile);
treeView1.Nodes.Clear();
if (xmlDocument.DocumentElement != null) treeView1.Nodes.Add(new TreeNode(xmlDocument.DocumentElement.Name));
//Creating TreeNode and adding the first node to it.
TreeNode tNodeObj = treeView1.Nodes[0];
//Creating XmlNodeList to load all the nodes of XML file in the list and
//initialising the XmlNode with first element of the xml filename.
XmlNode xNode = xmlDocument.DocumentElement;
//Declaring function for adding Nodes to tree View.
AddingNodesToTree(xNode,tNodeObj);
toolStripStatusLabel1.Text = "Opened file " + nameofFile;
treeView1.Nodes[0].Expand();
treeView1.CollapseAll();
}//try block ends
//Exception Handlers to catch any sort of error
catch (XmlException xmlex)
{
MessageBox.Show(xmlex.Message, "Error");
}//catch
catch (Exception exp)
{
txtFileName.Text = exp.Message;
}
}//initiatingTree
//Method to add Nodes to tree
private static void AddingNodesToTree(XmlNode xmlNode,TreeNode tnode)
{
//Adding nodes to tree while looping through the entire XML file
if (xmlNode.HasChildNodes)
{
XmlNodeList nodeList = xmlNode.ChildNodes;
for (int i = 0; i <= nodeList.Count - 1; i++)
{
XmlNode xmladdtreeNode = xmlNode.ChildNodes[i];
String nodetype = "" + xmladdtreeNode.NodeType;
if (nodetype.Equals("Text") || nodetype.Equals("Comment")) // if node type is text or comment
{
tnode.Nodes.Add(new TreeNode(xmladdtreeNode.InnerText)); // simply add it in the tree
}
else // else if it has children
{
String name = "<" + xmladdtreeNode.Name;
XmlAttributeCollection attCol = xmladdtreeNode.Attributes; // Collects all the attributes of a node in attCol
foreach (XmlAttribute xmlatt in attCol)
{
name += " " + xmlatt.Name + "=\"" + xmlatt.Value + "\"";
}
name += ">";
TreeNode tn = new TreeNode(xmladdtreeNode.Name);
tn.Text = name;
tnode.Nodes.Add(tn);
TreeNode treeNode = tnode.Nodes[i];
AddingNodesToTree(xmladdtreeNode,treeNode); // the method is called recursively to get all the child nodes and their attributes till the loop is over
}
}//for
}//if
else
{
tnode.Text = xmlNode.OuterXml.Trim(); //Removes all the white spaces when there are no children of the parent
}//else
}//AddingNodesToTree
//To show Attributes and values of selected Nodes.
private void treeView1_AfterSelect(object sender,TreeViewEventArgs e)
{
listBox1.Items.Clear();
TreeNode treenode = e.Node; //Node selected in Treeview
String text = treenode.Text;
String relevent = text;
Boolean flag = true;
while (flag)
{
int SpaceIndex = relevent.IndexOf(" ");
if (SpaceIndex != -1)
{
int indexofEqual = relevent.IndexOf('=', SpaceIndex);
if (indexofEqual != -1)
{
int indexOFValue = relevent.IndexOf("\"", indexofEqual + 2);
if (indexOFValue != -1)
{
String attribute = relevent.Substring(SpaceIndex + 1, indexofEqual - SpaceIndex - 1); //starts displaying the attribute name after space for the given length
String value = relevent.Substring(indexofEqual + 2, indexOFValue - indexofEqual - 2); //starts displaying the attribute value after "="sign for the given length
listBox1.Items.Add("Attribute : " + attribute + " Value : " + value); // add it in the list box
relevent = relevent.Substring(indexOFValue);
}
else
{
listBox1.Items.Add("Bad format of the xml file for this node");
flag = false;
}
}
else
{
flag = false;
}
}
else
{
flag = false;
}
}
}//AfterSelect()
//To select a XML file to be shown as treeview.
private void btnBrowse_Click(object sender,EventArgs e)
{
txtFileName.Clear(); //Clearing all the controls before loading any other xml file in Treeview.
listBox1.Items.Clear();
treeView1.Nodes.Clear();
ExpandBtn.Text = "Expand Tree Nodes";
bgWorker1.RunWorkerAsync();
StripProgressBar.Value = 0;
toolStripStatusLabel1.Text = "Browsing for a Xml file";
OpenFileDialog open = new OpenFileDialog();
open.InitialDirectory = @"C:\";//to start searching XML file with c directory.
open.Filter = "XML Files (*.xml)|*.xhtml|All files(*.*)|*.*";//to list only xml,xhtml and all files in browse window.
open.FilterIndex = 2;
open.RestoreDirectory = true;//Restore the old directory
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
initiatingTree(open.FileName); //this variable gives the name of selected file
}
while (this.bgWorker1.IsBusy)
{
StripProgressBar.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
}//Browse button
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
xmlDocument = new XmlDocument();
Thread.Sleep(5000);
xmlDocument.Load(txtFileName.Text);
btnBrowse.Enabled = false;
}
private void bgworker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Set progress bar to 100% in case it's not already there.
StripProgressBar.Value = 100;
if (e.Error == null)
{
MessageBox.Show(xmlDocument.InnerXml, "Download Complete");
}
else
{
MessageBox.Show(
"Failed to download file",
"Download failed",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
// Enable the Browse button and reset the progress bar.
this.btnBrowse.Enabled = true;
StripProgressBar.Value = 0;
toolStripStatusLabel1.Text = "work finished processing request.";
}//workerCompleted
}// TreeDisplay Class
}//namespace
Will be eagerly waiting for your reply.
Hope to find suitable help and guidance from you.
Thanks & Regards
RachS
Bechir BejaouiPosted Mar 9, 2009, 10:38 AM
Second, you can avoid using a backgroundworker and progressbars and so forth as the web client is here an enable you implement uploading tasks within asynchrone mode, to that user can lunch the loading operation a steps to perfrom a second action without worring about the uploading task except that his cancels it or some errors happen
private void Form1_Load(object sender, EventArgs e)
{
FileStream myFile = new FileStream(@"C:\myFile.xml", FileMode.Open);
Uri myUri = new Uri("uri string here");
byte[] b = new byte[myFile.Length];
myFile.Write(b, 0, b.Length);
WebClient client = new WebClient();
client.UploadDataAsync(myUri, b);
client.UploadDataCompleted+=new UploadDataCompletedEventHandler(client_UploadDataCompleted);
}
private void client_UploadDataCompleted(object sender, UploadDataCompletedEventArgs ue)
{
if (ue.Cancelled)
{
//TO DO: Write the behaviour when user press cancel uploading
}
if (ue.Error != null)
{
//The error is an exception that happens when something is wrong
/* TO DO: write a code to handle this situation for example redirect the
user to a default error page */
}
else
{
//TO DO: Write the behavio when the downloading is completed
}
}
Rach SinghPosted Mar 4, 2009, 10:28 AM
Thanks for reply,
i want a add a progress bar in status strip.This is because when a user uploads a large XML file then the window freeze so i want to add a progress bar here to tell the user that the application is working not freeze.Here is the code what i have done till now.
private void btnBrowse_Click(object sender,EventArgs e)
{
StripProgressBar.Value = 0;
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog(this) == DialogResult.OK)
{
txtFileName.Text = open.FileName;
initiatingTree(open.FileName);
bgWorker1.RunWorkerAsync();
}
while (this.bgWorker1.IsBusy)
{
StripProgressBar.Increment(1);
Application.DoEvents();
}
}//Browse button
private void bgWorker1_DoWork(object sender, DoWorkEventArgs e)
{
xmlDocument = new XmlDocument();
Thread.Sleep(5000);
xmlDocument.Load(txtFileName.Text);
btnBrowse.Enabled = false;
}
But i am geting an Null rferenceexception on this line xmlDocument.Load(txtFileName.Text);
Can you please tell whats wrong???
Bechir BejaouiPosted Mar 2, 2009, 10:33 AM
OK, This class that I had developed can do the job
public class XmlParser
{
public TreeView treeView;
public string Path { get; set; }
public XmlParser() { }
public XmlParser(string path , TreeView treeView)
{
this.Path = path;
this.treeView = treeView;
StreamReader oReader = new StreamReader(path);
string Content = oReader.ReadToEnd();
XElement xe = XElement.Parse(Content);
int i = 0;
List
foreach (XElement el in xe.Elements())
{
list.Add(new TreeNode(el.Name.ToString()));
foreach (XElement subel in el.Elements())
{
list[i].Nodes.Add(new TreeNode(subel.Name.ToString() + " : " + subel.Value));
}
foreach (XAttribute attr in el.Attributes())
{
list[i].Nodes.Add(new TreeNode(attr.Name.ToString() + " : " + attr.Value));
}
i++;
}
treeView.Nodes.AddRange(list.ToArray());
}
}
So what to do is to open a winfows project and add a treeview within it and ajust sizes and then call the constructor of that class by overloading it by the xml file path and the added treeview instance, any xml file will be parsed and respesented in the treeview as main and children nodes requardless of the given xml structure.
You have asked about progressbar what do you want to do exactly with it
Rach SinghPosted Mar 2, 2009, 4:43 AM
here s a brief descrpition of what i actually want:
Till now i have achieved the following.
The code that i have written till now displays the attributes in the listbox but for that it uses the element name in the tree view. But for instance we change the element name at any point of time then this application crashes. I want to develop a piece of code where i am independent of this restriction. I may make use of tags(thats whats coming to my mind) or i may apply some other method but i dont know how to make use of these in C#. Can you help me here? .NET includes some very useful XML processing classes that can do all that work for you , i know that. But what classes i dont know as i am a newbie. Can you please tell me what are these classes and how can i make use of them to get whats desired, that is displaying the attributes of an xml node in another pane in a window after that node is selected in the tree view in the same window.
Also if we make use of tags then how do we type cast a tag which is an object so that it contains the xml node?
Bechir BejaouiPosted Mar 1, 2009, 5:49 PM