Cant resolve infinite recursion - c#

Ive recently started coding on populating a treeview control from a list and this is where i am starting.
http://msmvps.com/blogs/deborahk/archive/2009/11/09/populating-a-treeview-control-from-a-list.aspx
I am currently trying to retrieve registry paths and storing them to a list. From that list, I am trying to add it as parent nodes to the treeview control. Then I traverse every level in the registry and add them as nodes eventually creating a tree-like replica of it. I am retrieving registry information through a separate process and I shy away from using the Registry API within c#. I incorporated all of the code in the link above to my current code and now i am experiencing an infinite recursion error everytime i compile.
This is the current code I am working on.
private void registry()
{
string hivelist_output = process.StandardOutput.ReadToEnd();
string[] hivelist_lines = Regex.Split(hivelist_output, "\r\n");
string[] registry_paths = new string[hivelist_lines.Length];
List<string> registry_path_list = new List<string>();
for (i = 0; i < hivelist_lines.Length; i++)
{
registry_paths[i] = hivelist_lines[i].Substring(22);
registry_path_list.Add(registry_paths[i].Trim());
}
for (i = 0; i < registry_path_list.Count; i++)
{
treeViewList.Add(new TreeViewItem()
{
ParentID = 0,
ID = i,
Text = registry_path_list[i]
});
}
PopulateTreeView(0, null);
treeView1.ExpandAll();
}
private void PopulateTreeView(int parentId, TreeNode parentNode)
{
var filteredItems = treeViewList.Where(item => item.ParentID == parentId);
TreeNode childNode = new TreeNode();
foreach (var i in filteredItems.ToList())
{
if (parentNode == null)
childNode = treeView1.Nodes.Add(i.Text);
else
childNode = parentNode.Nodes.Add(i.Text);
PopulateTreeView(i.ID, childNode);
}
}
The error of infinite recursion points me to this line of code and I dont understand why.
childNode = parentNode.Nodes.Add(i.Text);
I appreciate your great advice on this matter. Thanks in advance!
-------------------------------------SOLVED-------------------------------------------
Moving forward, now my next problem is to add the subkeys below each parent node (registry path) and as well as the subkeys below each of the previously retrieved subkeys and key values and data types. Since the registry is quite deep, how could i make it so that I plot all possible values without using too much nested loops? Thanks!
*structure of what I would like to achieve
registry path
- subkey1
- subkeys of subkey1
- subkeys of subkey1.1
- data types & values
-subkey 2
.
.
.
-subkey 3
.
.
.
-subkey n
- data types & values
so and so forth

You are adding TreeViewItems always with ID = 0. Therefore, your PopulateTreeView always calls itself recursively with ID 0.
You need to fix your setup method:
for (i = 0; i < registry_path_list.Count; i++)
{
treeViewList.Add(new TreeViewItem()
{
ParentID = 0,
ID = 0,
Text = registry_path_list[i]
});
}
and use the corresponding IDs.

Related

Unable to iterate to next ListNode, since the current node is getting overridden with the listnode.next value

This is a leetcode problem.
I saw the solution however while trying to use my own logic, I cannot iterate over to the next node.
public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
{
try
{
string l1NodeData = null;
string l2NodeData = null;
do
{
l1NodeData = l1NodeData + l1.val;
l1 = l1.next;
} while (l1 != null);
do
{
l2NodeData = l2NodeData + l2.val;
l2 = l2.next;
} while (l2 != null);
int sum = Convert.ToInt32(l1NodeData) + Convert.ToInt32(l2NodeData);
var sumInChar = sum.ToString().ToArray();
ListNode dummyhead = new ListNode(0);
ListNode ans = dummyhead;
for (int i = sumInChar.Length - 1; i > 0; i--)
{
ans.val = Convert.ToInt32(sumInChar[i].ToString());
ListNode tempListNode = new ListNode(Convert.ToInt32(sumInChar[i - 1].ToString()));
ans.next = tempListNode;
ans = ans.next;
//here(ans = ans.next) after assigning the next node, the data of the current node is getting overridden.
}
return ans;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
In the above solution where I am assigning ans = ans.next, there the current node is overridden with the next node, however, I just want to move to the next node in order to iterate.
Could someone please help me on this?
In the above solution where I am assigning ans = ans.next, there the current node is overridden with the next node, however, I just want to move to the next node in order to iterate.
The assignment is to a variable. That never mutates your linked list. This way of assigning to a variable is exactly what you need to traverse a linked list. It does not modify it. In order to mutate it, you will always need to assign to a member (property) of a node, like its next property.
In the code comments you wrote:
the data of the current node is getting overridden.
No, it looks like that because you return the reference to the last node that was created in the loop. Instead you should return dummyHead.next; This way you return the first node that was created in the loop.
In comments you wrote:
...I have not made any assignment to dummyhead right, then how does data reside in that variable?
You have referenced ans to the same node as dummyHead, and you did assign to ans.next, which in the first iteration of the loop is synonymous to dummyHead.next. With those assignments to ans.next the nodes get linked to eachother.
Note that dummyHead is an extra node that is created to ease the code in the loop -- not having to make a special case for creating the real head node. After the loop that dummyHead is then ignored (it served its purpose), and the real head (that is sitting right after it) is returned.

C# find a specific element with two or more xml files?

I try to explain my problem:
Okay, I need the KSCHL and the Info.
I need the KSCHL from the result file and then I want to search after the KSCHL in the other file "Data".
In the first file I have all KSCHL.
var kschlResultList = docResult.SelectNodes(...);
var kschlDataList = docData.SelectNodes(...);
var infoDataList = docData.SelectNodes(...);
for (int i = 0; i < kschlResultList.Count; i++)
{
string kschlResult = kschlResultList[i].InnerText;
for (int x = 0; x < kschlDataList.Count; x++)
{
string kschlData = kschlDataList[x].InnerText;
if (kschlData == kschlResult)
{
for (int y = 0; y < infoDataList.Count; y++)
{
string infoData = infoDataList[y].InnerText;
if (infoData == kschlResult)
{
//I know the If is false
string infoFromKschl = infoData;
}
}
}
}
}
The problem is now to find the KSCHL (from the first file) in the second file and then to search after the "info".
So if I have the KSCHL "KVZ1" in the first file, then I want to search this KSCHL in the second file and the associated Info for it.
Hope you understand :)
You don't have to loop quite so much. :-)
Using XPath - the special strings inside SelectNodes() or SelectSingleNode(), you can go pretty directly to what you want.
You can see a great basic example - several really - of how to select an XML node based on another node at the same level here:
How to select a node using XPath if sibling node has a specific value?
In your case, we can get to a list of the INFO values more simply by looping just through the KSCHL values. I use them as text, because I want to make a new XPath string with them.
I'm not clear exactly what format you want the results in, so I'm simply pushing them into a SortedDictionary for now.
At that last step, you could do other things as is most useful to you..... such as push them into a database, dump them in a file, send them to another function.
/***************************************************************
*I'm not sure how you want to use the results still,
* so I'll just stick them in a Dictionary for this example.
* ***********************************************************/
SortedDictionary<string, string> objLookupResults = new SortedDictionary<string, string>();
// --- note how I added /text()... doesn't change much, but being specific <<<<<<
var kschlResultList = docresult.SelectNodes("//root/CalculationLogCompact/CalculationLogRowCompact/KSCHL/text()");
foreach (System.Xml.XmlText objNextTextNode in kschlResultList) {
// get the actual text from the XML text node
string strNextKSCHL = objNextTextNode.InnerText;
// use it to make the XPath to get the INFO --- see the [KSCHL/text()= ...
string strNextXPath = "//SNW5_Pricing_JKV-Q10_full/PricingProcedure[KSCHL/text()=\"" + strNextKSCHL + "\" and PRICE>0]/INFO/text()";
// and get that INFO text! I use SelectSingleNode here, assuming only one INFO for each KSCHL..... if there can be more than one INFO for each KSCHL, then we'd need another loop here
string strNextINFO = docdata.SelectSingleNode(strNextXPath)?.InnerText; // <<< note I added the ? because now there may be no result with the rule PRICE>0.
// --- then you need to put this result somewhere useful to you.
// I'm not sure what that is, so I'll stick it in the Dictionary object.
if (strNextINFO != null) {
objLookupResults.Add(strNextKSCHL, strNextINFO);
}
}

GetDirectories - Retrieve only a few folders from the Directory

New to c# and ASP.net, I am working on retrieving Directories and have done so.
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ListItem item;
ListItem item
string folderLocation = #"\\serv5007i\TeamCityDeploy\Trunk Production Build\Current\bin\Runtime";
int startSize = folderLocation.Length+1;
string[] fileNames = Directory.GetDirectories(folderLocation);
foreach (string fileName in fileNames)
{
item = new ListItem();
item.Value = item.Text = "Add " + fileName.Substring(startSize);
CheckBoxList1.Items.Add(item);
CheckBoxList2.Items.Add(item);
CheckBoxList3.Items.Add(item);
}
}
}
}
So I have the output as the Directory of 15 or so folders. Is it possible to return only 10 and then 5 in another div.
So basically I have 15 folders being returned, but I need to have the bottom 5 under a different heading to the others. My apologies if I'm not being clear. Beginner!
You can control the output, when you execute Directory.GetDirectories you'll receive a collection. I believe in this instance, you'll receive a string array. This can be manipulated however you want:
Loop Example's:
foreach(string directory in directories)
{
// Enumerate over all items within the collection.
}
for(int index = 0; index < directories.Length; index++)
{
// Will enumerate until index == directories
// If you make index five, it would start at position six of the array.
// since they're zero based. But you can manipulate how you want.
}
do
{
index++
// Perform an action. Based on the while.
}
while(index != directories.Length);
while(index != directories)
{
index++;
// Perform action until equal.
}
The downfall to these approaches, are you're manipulating a integer for a starting position or ending position. Which can create confusion in the code. The other approach would be Linq, which similar to the above as far as iteration but will make the code a bit more expressive.
Linq Example's:
var filtered = directories.Take(10); // Take the first ten.
var filtered = directories.Skip(5); // Skip the first five.
var filtered = directories.Where(path => new DirectoryInfo(path).Name.Contains("Name")); // If directory names contain, return on that.
You could also do:
var filter = Directory.EnumerateDirectories(path)
.Where(directory => directory.Name.Contains("Sample"))
.Take(10);
So the initial line will automatically enumerate the directories within the provided path, you filter based on name, then take the first ten.
You can tackle this problem a lot of different ways, that is why narrowing it down would be more helpful.
"Go not to the Elves for counsel, for they will say both no and yes."
Update:
A full Linq example would be one of these two approaches:
var directories = Directory.GetDirectories(path);
var filtered = directories.Skip(5);
Or you could do it in a single line.
var filtered = Directory.EnumerateDirectories(path).Skip(5).Take(5);

Adding elements to an ordered list

I want to add an element to a linked list so that the list remains sorted. I wrote this function. He's got a place that should be included, but I do not know how to insert the element.
public void AddSorted(int num)
{
Node n = new Node(num);
Node curr = _first;
Node curr1 = _first.Link;
while (curr1.Data < n.Data && curr1 != null)
{
curr = curr.link;
curr1= curr1.link;
}
// how to add element ???
}
You have provided absolutely no context regarding your LinkedList class, so I can only make an educated guess.
Given what I understand from the above code, after traversing to the location you want to insert the new Node, you will need to set the link of Node curr1 (which is the last Node) to the new node object.
Node temp = curr1.Link; // store next Node in temporary object
curr1.Link = n; // Insert new Node
Remember that you need to set the link of the new node to the next node in the LinkedList in order to continue the LinkedList (if the newly inserted Node is not the last):
n.Link = temp;
Please let me know if I made a mistake understanding your code, I can then change my answer accordingly.
With the help of my dear friends.
I could write this function.
Below you can see the code :
public void AddSorted(int num)
{
Node n = new Node(num);
Node curr = _first;
if (_first == null || _first.Data >= n.Data)
{
n.Link = _first;
_first = n;
}
else
{
while (curr.Link != null && curr.Link.Data < n.Data)
{
curr = curr.Link;
}
n.Link = curr.Link;
curr.Link = n;
}

Unreachable Code Detected?

I am getting this rediculous error "unreachablecode detected" and clearly everything in in proper visibiliity...
Here is the code ..
int lastAppNum = 0;
//load the xml document
XmlDocument xdoc = new XmlDocument();
xdoc.Load(GlobalVars.strXMLPath);
//add a app node
XmlNode newApp = xdoc.CreateNode(XmlNodeType.Element, "app", null);
//add the app number - this will be used in order to easily identify the app details (used for overwriting/saving)
XmlAttribute newNum = xdoc.CreateAttribute("num");
//in order to create a new number - search the last num and add one to it
foreach (XmlNode xmlAppChild in xdoc.ChildNodes)
{
//if there are existing child nodes
if (true)
{
//get the last childs num attribute
lastAppNum = Convert.ToInt32(xmlAppChild.LastChild.Attributes["num"].Value);
//add +1 to the last app num
lastAppNum++;
//add the new value to the attribute
newNum.InnerText = lastAppNum.ToString();
break;
}else{
//if there isnt an existing child node - set the num to 1
lastAppNum = 1; <<where the error happens
newNum.InnerText = lastAppNum.ToString();
break;
}
}
Does anyone have an idea of whats going on ? I thought perhaps it was the lack of a "break" so i threw two in here (i saw on a form thats what a solution was) but either way it doesnt matter and the error is still happening. Any suggestions would be great.
You have if (true) - was there some condition you actually wanted to test here?
if (true)
{
// this code will always run
}
else
{
// this code will never run
}
else condition will never run since you have if (true)
i think based on your comments, you need to change the implimentation as below
if(xdoc.HasChildNodes)
{
foreach (XmlNode xmlAppChild in xdoc.ChildNodes)
{
//if there are existing child nodes
//get the last childs num attribute
lastAppNum = Convert.ToInt32(xmlAppChild.LastChild.Attributes["num"].Value);
//add +1 to the last app num
lastAppNum++;
//add the new value to the attribute
newNum.InnerText = lastAppNum.ToString();
}
}else
{
//if there isnt an existing child node - set the num to 1
lastAppNum = 1;
newNum.InnerText = lastAppNum.ToString();
}
the code
if (true)
will always be executed and there is no chance to else condition be executed.

Categories