I'm trying to make a project manager program, to help organize my project files. It uses Xdocs to store the project information.
My problem is that now I wish to include a more structured view of the files associated with the project. That should look like this when it is done (file part of the xml)
<files count="0">
<folder foldername="Doks">
<folder foldername="moks">
<folder foldername="Floks">
<doc>
<fileType>doc</fileType>
<filePath>G:\Doks\moks\Floks</filePath>
<fileName>Dok1.doc</fileName>
<fileID>0</fileID>
</doc>
</folder>
</folder>
<folder foldername="goks">
<folder foldername="Floks">
<doc>
<fileType>doc</fileType>
<filePath>G:\Doks\moks\Floks</filePath>
<fileName>Dok1.doc</fileName>
<fileID>0</fileID>
</doc>
</folder>
</folder>
</folder>
</files>
As you can see the main folder is doks that has two sup folders with sub folders and files it is all created for tests of course.
So far my code can find the already existing path, but cannot add the last part that is missing.
The reason for this is that I what the XML to resemble the reality, and that I have already made the GUI part of the system and it Works like a charm. Also it is easy to read
Here is the code.
// Folder is contains the path the file e.i.
// <folder foldername="Doks">
// <folder foldername="moks">
// <folder foldername="Floks"/>
// </folder>
// </folder>
// the file han the info about that
// the xdoc to insert/anex the file and folder too is FilesInProject that is a public xdocument property
private void AnexFileinXdoc(XElement file, XElement folder)
{
// is there even a folde to consider
if (folder != null)
{
// folder desendens list, used by looping through it to se how menny of the folder already exists
XElement[] list = new XElement[1];
// handle for only on folder
if (folder.Elements().Count() > 0)
{
list = folder.DescendantsAndSelf().ToArray();
}
else
{
list[0] = folder;
}
// debug info ignore
// XElement[] test = FilesInProject.Root.DescendantsAndSelf("folder").ToArray();
// list of the folderes already found this was to insure that when the loop resets and checks for the nex folder i will not flag the previous as not created..
List<XElement> foundFolders = new List<XElement>();
for (int i = 0; i < list.Length; i++)
{
if (FilesInProject.Root.Elements().Count() > 0)
{
foreach (XElement xelem in FilesInProject.Root.Elements("folder"))
{
if (xelem.FirstAttribute.Value == list[i].FirstAttribute.Value)
{
foundFolders.Add(xelem);
break;
}
else
{
if (!foundFolders.Contains(xelem))
{
list[i].DescendantsAndSelf().Last().Add(file);
xelem.Add(list[i]);// <-- here is the problem
}
else if (i == list.Length-1)
{
xelem.Add(file); //<-- here is the problem
}
}
}
}
}
}
else
{
FilesInProject.Root.Add(file);
}
}
What I expected was that: When I foreached through the decedents to find were to add my folder structure to the xelement that if I found it I could just call add on that element(xelem) and the FilesinProject xdoc would be updated, sadly it do not do this and I haven’t been able to find anything here on the matter.
I need a quick and simple way to merge the two structures together so I don’t get any duplicates
Found the solution and thought I should share it here
In the Else block
if (!foundFolders.Contains(xelem))
{
list[i].DescendantsAndSelf().Last().Add(file);
xelem.Add(list[i]);// <-- here is the problem
}
else if (i == list.Length-1)
{
xelem.Add(file); //<-- here is the problem
}
all I had to do was to change xelem.Add() to a query like this
if (!foundFolders.Contains(xelem))
{
list[i].DescendantsAndSelf().Last().Add(file);
FilesInProject.Descendants("folder")
.Where(item => item.Attribute("foldername").Value == xelem.FirstAttribute.Value).FirstOrDefault()
.Add(list[i]);
}
else if (i == list.Length-1)
{
FilesInProject.Descendants("folder")
.Where(item => item.Attribute("foldername").Value == xelem.FirstAttribute.Value).FirstOrDefault()
.Add(file);
}
and it works perfectly :)
Hope it helps others too