简体   繁体   中英

Iterating through Xdoc decendends adding Xelements

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM