See my current answer code below. This is a work in progress because Testdome says it is 50% correct. Current answer code passes 2 of Testdome's 4 unit tests. This is bewildering to me since it passes all my unit tests.
Testdome unit test results:
Example case: Correct answer
All folder names start with starting letter: Correct answer
Root folder name starts with starting letter: Wrong answer*
Complicated folder structure: Wrong answer*
*Wrong answers above reveals: "Your code returned a wrong answer for the test case. Create your own test cases to figure out where the code goes wrong."
EDIT
I also requested "Show hint", and the Testdome engine presented this:
Hint 1: XDocument provides a convenient LINQ based approach to parsing XML.
This is interesting because it would change my answer completely. With this I don't believe recursive function is required. Using LINQ, it would be possible to just build the resulting list from the deserialized Xml. I will work on that and post back my findings...
My first answer code (using recursion -- WRONG ANSWER -- keep reading):
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
[XmlRoot(ElementName = "folder")]
public class Folder
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "folder")]
public List<Folder> children { get; set; }
}
public class Folders
{
public static IEnumerable<string> FolderNames(string xml, char startingLetter)
{
XmlSerializer serializer = new XmlSerializer(typeof(Folder));
StringReader reader = new StringReader(xml);
Folder folders = (Folder)serializer.Deserialize(reader);
searchFolders(folders, startingLetter);
reader.Close();
return searchFolderResults;
}
private static List<string> searchFolderResults = new List<string>();
private static void searchFolders(Folder node, char startingLetter)
{
if (node.Name.StartsWith(startingLetter.ToString()))
{
searchFolderResults.Add(node.Name);
}
foreach (Folder folder in node.children)
searchFolders(folder, startingLetter);
}
public static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<folder name=\"c\">" +
"<folder name=\"program files\">" +
"<folder name=\"uninstall information\" />" +
"<folder name=\"cusers3\" />" +
"</folder>" +
"<folder name=\"users\">" +
"<folder name=\"users2\" />" +
"</folder>" +
"</folder>";
foreach (string name in Folders.FolderNames(xml, 'c'))
Console.WriteLine(name);
}
}
EDIT
My latest code (using XDocument and LINQ, and another unit test passing):
Testdome unit test results:
Example case: Correct answer
All folder names start with starting letter: Correct answer
Root folder name starts with starting letter: Correct answer
Complicated folder structure: Wrong answer*
*Wrong answers above reveals: "Your code returned a wrong answer for the test case. Create your own test cases to figure out where the code goes wrong."
I hit up the "Show hint" again, and now it has a 2nd hint:
Hint 2: The root node of a document may also need to be considered.
So I am off again to keep working until I resolve all the Testdome unit tests. They claim this is a hard C# problem. I suppose...
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
[XmlRoot(ElementName = "folder")]
public class Folder
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "folder")]
public List<Folder> children { get; set; }
}
public class Folders
{
public static IEnumerable<string> FolderNames(string xml, char startingLetter)
{
return
from row in XDocument.Parse(xml).Descendants()
where row.FirstAttribute.Value.StartsWith(startingLetter.ToString())
select row.FirstAttribute.Value;
}
public static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<folder name=\"c\">" +
"<folder name=\"program files\">" +
"<folder name=\"uninstall information\" />" +
"<folder name=\"cusers3\" />" +
"</folder>" +
"<folder name=\"users\">" +
"<folder name=\"users2\" />" +
"</folder>" +
"</folder>";
foreach (string name in Folders.FolderNames(xml, 'c'))
Console.WriteLine(name);
}
}
LAST EDIT ( I promise)
The issue with my latest answer above (involving XDocument and LINQ) is that I had used Contains
instead of StartsWith
, and this failed on a complex test where "cusers3" was not being filtered when searching for "u". After correcting this logic it works flawless in Testdome's test engine. Thanks!!
BTW.. the 2nd hint (see above) was a red herring (not the fishy kind).