Avatar of vbMarkO
vbMarkO
 asked on

Parse directories and get info from folder names

Ok my folders are like this IE:

Vehicle_DB
        |_______Ford_F-150
                              |________2010_Ford_F-150
                              |________2009_Ford_F-150
        |
        |_______Ford_Mustang
                              |________2010_Ford_Mustang
                              |________2009_Ford_Mustang
                              |___________> More like above all the way to 1990
 
     There are also folders that are Dodge, Chevy, Toyota and just about every car you can think of

   Most folders will span 20 years ... 1990 to 2010
HOWEVER, some Models do not span that many years they may only span for example
from 2000 to 2005 and so on

What I need is this

  I have 3 comboBoxes
cbYear
cbMake
cbModel
If user for example selects the following;

cbYear.text = "2007" then selects cbMake.Text = "Ford"

Once year and make are selected then the directories I described would be parsed so that

cbModel would only display all Ford models that existed in 2007


Now maybe parsing directories each time is not efficient and it might be better to parse the directories once and create an XML file with all the needed info in them

This would be fine as I know how to parse xml just fine and would allow me to add other data for specific vehicles as needed

But I havent a cluse how to parse directory folder names and get the info fro them to create an xml so I might have access to the info

ANy examples of how I might go about this or accomplish this

Personally it seems more logical to put into an XML file but I really dont know ... I need help here

 
.NET ProgrammingVisual Basic.NET

Avatar of undefined
Last Comment
Fernando Soto

8/22/2022 - Mon
vbMarkO

ASKER
I am leaning more and more toward an XML file as it would also allow me to add vehicle description to it

SO maybe we could parse the directories and put into an xml file LIKE this

<?xml version="1.0" encoding="utf-8"?>
<Vehciles>
      <VehMods>
             <Make>Ford</Make>
             <Model>F-150</Model>
            <Years>1990 - 2010</Years>
            <1990_Ford_F-150>Description/Data goes here  </1990_Ford_F-150>
            <1991_Ford_F-150>Description/Data goes here  </1991_Ford_F-150>
            <1992_Ford_F-150>Description/Data goes here  </1992_Ford_F-150>
            <1993_Ford_F-150>Description/Data goes here  </1993_Ford_F-150>
                          AND SO ON ......
       </Vehicles>

This makes sense as it will allow me to add other data and or needed info to specific Year of model


Just my thoughts
Mike Tomlinson

So the bottom level directory names are:

    2010_Ford_F-150
    2009_Ford_F-150
    2010_Ford_Mustang
    2009_Ford_Mustang

Can we simply split each name on _ (underscore) to get the year, make, model?

Are there always three parts to the name?...so we could differentiate between the 2nd level and the 3rd level?
vbMarkO

ASKER
So the bottom level directory names are: YES

    2010_Ford_F-150
    2009_Ford_F-150
    2010_Ford_Mustang
    2009_Ford_Mustang

 

Can we simply split each name on _ (underscore) to get the year, make, model?  YES

Are there always three parts to the name?...so we could differentiate between the 2nd level and the 3rd level?  YES



Yes to all 3 questions!

Directory above Subdirectories are always ... Make_Model
Subdirectories are always ...............................    Year_Make_Model

:)

Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Fernando Soto

Hi vbMarkO;

You can not start an XML node with a number such as this <1990_Ford_F-150>. I re-structured your XML a little. The Linq query below is based on this XML Document.

<?xml version="1.0" encoding="utf-8"?>
<Vehciles>
    <VehMods>
        <Make Name="Ford">
            <Model Name="F-150">
                <Years>1990 - 2010</Years>
                <Ford_F-150_2010>Description/Data goes here  </Ford_F-150_2010>
                <Ford_F-150_1990>Description/Data goes here  </Ford_F-150_1990>
                <Ford_F-150_1991>Description/Data goes here  </Ford_F-150_1991>
                <Ford_F-150_1992>Description/Data goes here  </Ford_F-150_1992>
                <Ford_F-150_1993>Description/Data goes here  </Ford_F-150_1993>
            </Model>
            <Model Name="Mustang">
                <Years>1990 - 2010</Years>
                <Ford_Mustang_2010>Description/Data goes here  </Ford_Mustang_2010>
                <Ford_Mustang_2009>Description/Data goes here  </Ford_Mustang_2009>
            </Model>
        </Make>        
    </VehMods>
</Vehciles>
Dim xDoc As XDocument = XDocument.Load("Vehicle.xml")

Dim models = (From make In xDoc.Descendants("Make") _
              Where make.Attribute("Name") = cbMake.Text _
              From model In make.Descendants("Model").Elements() _
              Where model.Name.LocalName.EndsWith(cbYear.Text) _
              Select model).ToArray()

cbModel.Items.Clear()
cbModel.Items.AddRange(models)

Open in new window

vbMarkO

ASKER
FernandoSoto,

  FIrst off subject just a comment abut LINQ I just love the simplicity of it .... its so easy to read and understand ...

Ok, on subject:

   I like the structure of the XML it makes sense, I didn't think of this exactly .... I like the way the various makes are structured.

  I can see how this would facilitate adding the Models to the cbModel items list ....

But before I could implement this or accept this I know there are others working on this too and are including the parsing of the directories to assist in the creation of the xml file based on what is in the directories as mentioned above.

  I really like what I see here too ... once I see what else comes here I will try and determine what way will best be applicable to my needs here.


Will get back as I see what develops
Fernando Soto

Hi vbMarkO;

The following XML document was created in VB code in the code snippet below. It used the directory structure from the original post.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Vehicle_DB>
  <Ford_F-150>
    <Ford_F-150_2009 />
    <Ford_F-150_2010 />
  </Ford_F-150>
  <Ford_Mustang>
    <Ford_Mustang_2009 />
    <Ford_Mustang_2010 />
  </Ford_Mustang>
</Vehicle_DB>

Fernando
Imports System.IO
Imports System.Xml.Linq

' The location of the start of the file structure
Dim startPath As String = "C:\Vehicle_DB"
Dim dirInfo As New DirectoryInfo(startPath)
Dim xDoc As New XDocument(New XDeclaration("1.0", "utf-8", "yes"), New XElement("Vehicle_DB"))
Dim root As XElement = xDoc.Root

For Each dir As DirectoryInfo In dirInfo.GetDirectories()
    Dim newDir As New XElement(dir.Name)
    Dim fileInfo() As FileInfo = dir.GetFiles()
    For Each vicInfo As FileInfo In dir.GetFiles()
        ' Xml tag name can not start with numbers to put the date on the end
        Dim vicName As String = vicInfo.Name.Substring(0, vicInfo.Name.LastIndexOf("."c)) _
                                .Substring(vicInfo.Name.IndexOf("_"c) + 1) & "_" & _
                                vicInfo.Name.Substring(0, vicInfo.Name.IndexOf("_"c))
        Dim newFile As New XElement(vicName)
        newDir.Add(newFile)
    Next
    root.Add(newDir)
Next

xDoc.Save(startPath & "\Vehicle_DB.xml")

Open in new window

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Fernando Soto

In my las post I assumed that in your directory structure items like this were files and not firectories.  2010_Ford_Mustang
Fernando Soto

Type O's in my last post should be this :

In my last post I assumed that in your directory structure items like this were files and not directories:  2010_Ford_Mustang
Mike Tomlinson

Thanks for posting that Fernando...I haven't had time today to get back to this one.  =)
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
vbMarkO

ASKER
No, thats a folder name which contains with in it nothing but images.
  You can see the directory structure in the question body like this

Vehicle_DB
        |_______Ford_F-150
                              |________2010_Ford_F-150
                              |________2009_Ford_F-150
        |
        |_______Ford_Mustang
                              |________2010_Ford_Mustang
                              |________2009_Ford_Mustang
                              |___________> More like above all the way to 1990
 
     There are also folders that are Dodge, Chevy, Toyota and just about every car you can think of

   Most folders will span 20 years ... 1990 to 2010
HOWEVER, some Models do not span that many years they may only span for example
from 2000 to 2005 and so on
Main directory
Vehicle_DB  <-------- this is the main DIR
     Ford_F-150  <---- Example of a Sub DIR
            2010_Ford_F-150 <--- Bottom level DIR which contains all 2010 images of the F-150
            2009_Ford_F-150 <---- DIR containing all 2009 images for this vehicle
and so on



Fernando Soto

Hi vbMarkO;

Now it is reading all directories. It will construct an XML element for each directory and for each of its directories. See sample XML below with an extra directory and sub directory. The code snippet has the modified code.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Vehicle_DB>
  <Ford_F-150>
    <Ford_F-150_2009 />
    <Ford_F-150_2010 />
  </Ford_F-150>
  <Ford_Mustang>
    <Ford_Mustang_2009 />
    <Ford_Mustang_2010 />
  </Ford_Mustang>
  <Mercury_Grabd_Marquis_LS>
    <Mercury_Grand_Marquis_LS_2009 />
    <Mercury_Grand_Marquis_LS_2010 />
  </Mercury_Grabd_Marquis_LS>
</Vehicle_DB>
Dim startPath As String = "C:\Vehicle_DB"
Dim dirInfo As New DirectoryInfo(startPath)
Dim xDoc As New XDocument(New XDeclaration("1.0", "utf-8", "yes"), New XElement("Vehicle_DB"))
Dim root As XElement = xDoc.Root

For Each dir As DirectoryInfo In dirInfo.GetDirectories()
    Dim newDir As New XElement(dir.Name)
    Dim vicDir() As DirectoryInfo = dir.GetDirectories()
    For Each vicInfo As DirectoryInfo In dir.GetDirectories()
        Dim vicName As String = vicInfo.Name.Substring(vicInfo.Name.IndexOf("_"c) + 1) & "_" & _
                                vicInfo.Name.Substring(0, vicInfo.Name.IndexOf("_"c))
        Dim newVicDir As New XElement(vicName)
        newDir.Add(newVicDir)
    Next
    root.Add(newDir)
Next

xDoc.Save(startPath & "\Vehicle_DB.xml")

Open in new window

Fernando Soto

Sorry remove this line of code from the first For Each loop.

Dim vicDir() As DirectoryInfo = dir.GetDirectories()
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
vbMarkO

ASKER
OK this looks good I will go and try it but before I fire this up

Question: Since my Bottom Level directories are like this
                2010_Ford_F-150

               But what your creating in the xml is like
                Ford_F-150_2010

Will I need to rename my exiting folders to the same structure ... with the year at the end of the folder name? Or does this code switch them  as they are?

Going to set this up for testing now




Fernando Soto

An XML node name can't start with a digit so the best way would be to rename the directory so that it does not start with a digit. If you need to use the element name as the directory to find it on your system then rename the directory or add an attribute having the correct directory name and use it.
vbMarkO

ASKER
Getting an error: The ' ' character, hexadecimal value 0x20, cannot be included in a name.

NOTE: I made a couple of changes to code but I am pretty sure the changes shouldnt effect but here is the code as I am suing it

If its my fault I will try again without the changes

You can see the changes as they are commented
Dim dirInfo As New DirectoryInfo(myFolderPath) ' myFolderPath instead of stringPath
        Dim xDoc As New XDocument(New XDeclaration("1.0", "utf-8", "yes"), New XElement("Vehicle_DB"))
        Dim root As XElement = xDoc.Root

        For Each dir As DirectoryInfo In dirInfo.GetDirectories()
            Dim newDir As New XElement(dir.Name)
            ' This line removed as you said
            For Each vicInfo As DirectoryInfo In dir.GetDirectories()
                Dim vicName As String = vicInfo.Name.Substring(vicInfo.Name.IndexOf("_"c) + 1) & "_" & _
                                        vicInfo.Name.Substring(0, vicInfo.Name.IndexOf("_"c))
                Dim newVicDir As New XElement(vicName)
                newDir.Add(newVicDir)
            Next
            root.Add(newDir)
        Next

        xDoc.Save("Models.xml") ' INstead of saving it to Vehicles_DB I removed that ... I am assumming of course that this will save to application directory 
YES?

Open in new window

Your help has saved me hundreds of hours of internet surfing.
fblack61
vbMarkO

ASKER
You said; "An XML node name can't start with a digit so the best way would be to rename the directory so that it does not start with a digit. If you need to use the element name as the directory to find it on your system then rename the directory or add an attribute having the correct directory name and use it."

My question was though does your code take the existing directories as they are named and create the xml strucutre you gave as an example
  In other words
    Does your code take my 2010_Ford_F-150 subDirectory and create the xml tag <Ford_F-150_2010>?
Fernando Soto

To your question, "Does your code take my 2010_Ford_F-150 subDirectory and create the xml tag <Ford_F-150_2010>?", yes it does. I also stated that you need a reference to the correct directory name then you could do this, <Ford_F-150_2010 Dir="2010_Ford_F-150">.

On what line in the code are you getting the error. I did test on my system and had no problem.

vbMarkO

ASKER
Ahh I see what you are saying could make the correct directory as an attribute Yes?

Also the error was on this line
Line: 6:     Dim newDir As New XElement(dir.Name)
 
Error said; The ' ' character, hexadecimal value 0x20, cannot be included in a name.

I hope my 2 changes I made and mentioned in previous post aren't the cause!

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Fernando Soto

Does one of your directories have a space character in it? For example something like this, 2010_Ford F-150, where it should have been this, 2010_Ford_F-150.
vbMarkO

ASKER
Hmm I dont think so ... but I can check ... but the reason I do not think so is all the directories were created by the same code ...

But all things are possible I suppose
Be right back
vbMarkO

ASKER
Ahh I think Yes ....

FOr instance the code creates directories using Year_Make_Model and it does this everytime the same way

But the MODEL is the problem here because the model might be  Silverado 1500 Theres the space .... and note I have hundreds of directories that are like this
That might look like this

           2010_Chevrolet_Silverado 1500

The directories were created when I downloaded images from the web creating the directories and their subdirectories from the file names that already existed on the web where I got them ....

   When it was done I never looked ahead thinking I would run into this ... so they are as they are

This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ASKER CERTIFIED SOLUTION
Fernando Soto

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
vbMarkO

ASKER
Fernando this worked perfectly

   I can use this though the xml structure is not something I am used to ... never done a LINQ query before that mainly searches attributes

SO ... I am going now to go and create a question asking how to parse this XML using LINQ

Please look for it because you done so much already you deserve the other points to I beleive.

Thank you for your attention to this

The last code you posted I will consider the solution
vbMarkO

ASKER
Very Helpful, pointed out errors in my original structure and suggested a new structure and provided examples ... working through until we had a great solution

Thank You for such great effort
Fernando Soto

Not a problem, glad I was able to help.  ;=)
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.