Mapping TreeView to/from xmldoc

Hi,
Developing a trad win app using VS 2010 C#.

Starting from loading a xml file into a XMLDocument object.

 
openedFile = someFile.xml;
xmlReader = new XmlTextReader(openedFile);
Global.mainXMLDoc.Load(xmlReader);
xmlReader.Close();

Open in new window


Next thing I do is load the xml nodes into a TreeView component (System.Windows.Forms)

 
private void AddNodeToTreeView(ref XmlNode inXmlNode, ref TreeNode inTreeNode)
	{
		XmlNode xNode;
		TreeNode tNode;
		XmlNodeList nodeList;
		
		if (inXmlNode.HasChildNodes)
		{
			nodeList = inXmlNode.ChildNodes;
			for (int i = 0; i <= nodeList.Count - 1; i++)
			{
				xNode = inXmlNode.ChildNodes[i];
				inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
				tNode = inTreeNode.Nodes[i];
				AddNodeToTreeView(ref xNode, ref tNode);
			}
		}
	}

Open in new window


Now I have a multi column ListView to show the attributes whenever user selects a node from the TreeView component. Here's where it all gets totally wrong. My first idea was to use the tv.SelectedNode.Index (in the TreeView event listener _AfterSelect). But since this index is calculated relatively its parent the mapping to the xmlNodes is lost.

private void treeView_AfterSelect(object sender, TreeViewEventArgs e, TreeView tv, ListView lv)
{
	lv.Items.Clear();
	ListViewItem lvItem;
	currentNodeName = tv.SelectedNode.Text;
	int currentNodeIx = tv.SelectedNode.Index;
	xmlNodes = Global.mainXMLDoc.GetElementsByTagName(currentNodeName);
	XmlNode xNode = xmlNodes.Item(currentNodeIx);
	string attr;
	string val;

	for (int i = 0; i < xNode.Attributes.Count; i++)
	{
		attr = xNode.Attributes[i].Name;
		val = xNode.Attributes[i].Value;
		lvItem = new ListViewItem(attr);
		string foo = FindXPath(xNode.Attributes[i]);
		lvItem.SubItems.Add(val);
		lvItem.SubItems.Add(foo);
		lv.Items.Add(lvItem);
	}
}

Open in new window


So, is there a way you can do this using these standard components or do I need to design my own?

Cheers!
peer754Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MlandaTCommented:
in your XML file... are there any unique properties on each node? say an ID of sorts? or can you post a sample of of the xml file.
0
peer754Author Commented:
Noop, but I'm gonna try to use the HashCode function from the xmlNode object but how do I know that this would be unique for every xml node?

Here's a small sample from my xml:

 
<Organisation>
    <MainGroup dataName="SA">
      <HeadGroup dataName="SAA">
        <PlannerGroup dataName="C02"></PlannerGroup>
        <PlannerGroup dataName="C03"></PlannerGroup>
        <PlannerGroup dataName="C04"></PlannerGroup>
        <PlannerGroup dataName="C05"></PlannerGroup>
      </HeadGroup>
      <HeadGroup dataName="SAB">
        <PlannerGroup dataName="C36"></PlannerGroup>
        <PlannerGroup dataName="C37"></PlannerGroup>
      </HeadGroup>
    </MainGroup>
    <MainGroup dataName="SB">
      <HeadGroup dataName="SBB">
        <PlannerGroup dataName="C12"></PlannerGroup>
        <PlannerGroup dataName="C13"></PlannerGroup>
        <PlannerGroup dataName="C14"></PlannerGroup>
        <PlannerGroup dataName="C15"></PlannerGroup>
      <PlannerGroup dataName="C23"></PlannerGroup></HeadGroup>
      <HeadGroup dataName="SBC">
        <PlannerGroup dataName="C30"></PlannerGroup>
        <PlannerGroup dataName="C31"></PlannerGroup>
        <PlannerGroup dataName="C32"></PlannerGroup>
      </HeadGroup>
      <HeadGroup dataName="SBD">
      	<PlannerGroup dataName="C41"></PlannerGroup>
        <PlannerGroup dataName="C44"></PlannerGroup>
      </HeadGroup>
      <HeadGroup dataName="SBE">
      	<PlannerGroup dataName="C19"></PlannerGroup>
      </HeadGroup>
    </MainGroup>
  </Organisation>
  <World>
    <Region dataName="Region North America" ShortName="RNA">
      <SubRegion dataName="11">
        <Country dataName="US" LongName="United States"/>
        <Country dataName="CA" LongName="Canada"/>
      </SubRegion>
    </Region>
    <Region dataName="Region Latin America" ShortName="RLA">
      <SubRegion dataName="21">
        <Country dataName="BM" LongName="Bermuda"/>
      </SubRegion>
      <SubRegion dataName="22">
        <Country dataName="BB" LongName="Barbados"/>
        <Country dataName="CO" LongName="Colombia"/>
        <Country dataName="PE" LongName="Peru"/>
        <Country dataName="VE" LongName="Venezuela"/>
      </SubRegion>
      <SubRegion dataName="24">
        <Country dataName="BO" LongName="Bolivia"/>
        <Country dataName="CL" LongName="Chile"/>
      </SubRegion>
    </Region>
  </World>

Open in new window

0
MlandaTCommented:
you can use XPath to find the right node... not clean, but might work. to do this... perhaps start with this change - this keeps track of more details there:

inTreeNode.Nodes.Add(new TreeNode(xNode.Name));

Open in new window


should be:

TreeNode newNode = new TreeNode();

newNode.Text = xNode.Name;
newNode.Text = xNode.Attributes["dataName"].Value;

inTreeNode.Nodes.Add(xn);

Open in new window


do you have a screenshot of what the multi column ListView should look like?
0
Learn Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

MlandaTCommented:
i the HashCode can give us a unique value then by all means! use that! it "might" make life "easier". we will still have the problem of linking the hashcode back to the XML file
0
peer754Author Commented:
Ok, as far as I've been able to test this the HashCode seems to work fine :D
This is how I did it:

I first copy the HashCode from the xmlNode (xNode) into the TreeNode (tNode) using the .Name property of the tNode:

 
private void AddNodeToTreeView(ref XmlNode inXmlNode, ref TreeNode inTreeNode)
{
	XmlNode xNode;
	TreeNode tNode;
	XmlNodeList nodeList;
	
	if (inXmlNode.HasChildNodes)
	{
		nodeList = inXmlNode.ChildNodes;
		for (int i = 0; i <= nodeList.Count - 1; i++)
		{
			xNode = inXmlNode.ChildNodes[i];
			inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
			tNode = inTreeNode.Nodes[i];
			tNode.Name = xNode.GetHashCode().ToString();                   
			AddNodeToTreeView(ref xNode, ref tNode);
		}
	}
}

Open in new window


Now I can look up the corresponding xNode i.e. re-map the tNode by looking-up the HashCode:

 
private void treeView_AfterSelect(object sender, TreeViewEventArgs e, TreeView tv, ListView lv)
{
	lv.Items.Clear();
	ListViewItem lvItem;		// Used for creating listview items.

	currentNodeName = e.Node.Text;
	xmlNodes = Global.mainXMLDoc.GetElementsByTagName(currentNodeName);
	XmlNode xNode = null;
	foreach (XmlNode xn in xmlNodes)
	{
		if (string.Compare(xn.GetHashCode().ToString(), e.Node.Name) == 0)
		xNode = xn;
	}

	string attr;
	string val;

	if (xNode != null)
	{
		for (int i = 0; i < xNode.Attributes.Count; i++)
		{
			attr = xNode.Attributes[i].Name;
			val = xNode.Attributes[i].Value;
			lvItem = new ListViewItem(attr);
			string foo = FindXPath(xNode.Attributes[i]);
			lvItem.SubItems.Add(val);
			lvItem.SubItems.Add(foo);
			lv.Items.Add(lvItem);
		}
	}
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
peer754Author Commented:
Using the HashCode to map a TreeNode to/from a XMLNode seems to do the trick!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.