Relative folder paths

Hopefully that will be an easy one for the cracks here. For naming purposes I would like to have a string of the parent folder(s) relative to the current data folder.
I am doing it like this right now:

Function relative_path()

    string prefix
        NewDataFolder root:Test
    NewDataFolder root:Test:Test1
    NewDataFolder root:Test:Test1:Test2
    SetDataFolder root:Test:Test1:Test2
   
    DFREF dfr=GetDataFolderDFR()
   
    SetDatafolder :::
    prefix=GetDataFolder(0)
    SetDataFolder dfr
    print prefix
   
end


There must be an easier way to avoid messing with the SetDataFolder operation. I would love to have a solution where I can store the name of a folder relative to the current folder with like one command.

If I want to use the string-related commands like ::GetDataFolder(0) I get told that I cannot access a non-existent data folder even if I assign it to a string first. It is all quite confusing to me.

Can anyone help me?
Something like the following

Function DoStuff()
    NewDataFolder/S/O root:A
    NewDataFolder/S/O root:A:B
    NewDataFolder/S/O root:A:C
   
    string path = "::B"

    print GetDataFolder(1)
   
    SetDataFolder $path
   
    print GetDataFolder(1) 
End


outputs
root:A:C: root:A:B:
Thank you Thomas but except for the DFREF your solution is kind of similar to my example that was already working, isn't it? And it would only work for going up one level, as far as I can see. But I need two levels at least and importantly, no literal names but referenced folder names as strings.
I thought there might be something where I can avoid the whole "SetDataFolder" operation altogether.
But I just realized that it is probably inherently not possibly to just access the foldername of a parent folder withouht setting it first.

Something like this will not work ("Tried to access parent folder of root folder or a non-existent data folder"), although I do not really understand why.
Function DoStuff()
    NewDataFolder/S/O root:A
    NewDataFolder/S/O root:A:B
    NewDataFolder/S/O root:A:C
 
    string path2=GetDataFolder(0)
    string path = :::$path2
 
    print GetDataFolder(1)
 
    SetDataFolder $path
 
    print GetDataFolder(1) 
End


By the way it does not matter whether it is GetDataFolder(1) or (0).
I do understand that the possible results of :::$path2 do not make sense to pass to a string, because without any folder operation it is not clear what is implied. But I do not understand the error message. As if Igor already checks the existence of folders at compile time?
Maybe something like this helps?
Function relative_path()
 
    NewDataFolder root:Test
    NewDataFolder root:Test:Test1
    NewDataFolder root:Test:Test1:Test2
   
    string sDF = "root:Test:Test1:Test2"
    DFREF dfr=$sDF
    SetDataFolder dfr
    print GetDataFolder(1)
   
    string sDFparent=GetParentDF(sDF)
    DFREF dfr=$sDFparent
    SetDataFolder dfr
    print GetDataFolder(1)
end

Function/S GetParentDF(sDF)
    string sDF
    variable vPos = strsearch(sDF, ":", Inf, 1)  // search for ":" backwards from end
    if (vPos != -1 ) // found ":"
        sDF = sDF[0, vPos -  1] // remove last item
    endif
    return(sDF)
End


Kurt
That definitely solves my problem, however, your solution for solving my "issue" is not as easy as I thought it would be. Anyway, I will incorporate your suggestion, thank you. Your subfunction for reducing the pathlength is really cool and simple, thanks for that, too!
I know this post is old, but I have some code that handles this sort of thing at https://github.com/yamad/igorutils . The RefPath_resolve function in refpathutils.ipf will give you back a string containing the full object reference path. In your case, you can get the parent folder with RefPath_resolve("::"). You can use it like:

#include "refpathutils"
Function/S relative_path()
        NewDataFolder root:Test
    NewDataFolder root:Test:Test1
    SetDataFolder root:Test:Test1

        // ":" is current folder, extra ":" climb up the folder hierarchy
        print RefPath_resolve(":")     // current folder,           "root:Test:Test1:"
        print RefPath_resolve("::")    // parent folder,            "root:Test:"
        print RefPath_resolve(":::")   // parent-parent folder, "root:"
        print RefPath_resolve("::::")  // gives the root if you ask for too many levels

        return RefPath_resolve("::")
end


If I understand your goal correctly, this function was designed for your situation. You can specify reference paths as a string and you get back "the right" absolute path as a string. The path does not have to point to something that exists, so you can use it to create names for something you want to create:

Function create_sister_folder()
   NewDataFolder root:a
   NewDataFolder root:a:b
   SetDataFolder root:a:b

   String folderpath = "::c"      // a sister folder named "c"
   NewDataFolder $RefPath_resolve(folderpath)     // creates `root:a:c`

   SetDataFolder root:a
   NewDataFolder $RefPath_resolve(folderpath)     // creates `root:c`
End
To get the parent data folder of the current data folder you can use:
DFREF CurrentFolder=GetDataFolderDFR()
DFREF ParentFolder=$(GetDataFolder(1, CurrentFolder)+":")

Another GetDataFolder will give you the string value, if that's what you're interested in. I have this solution from another post here on Igor Exchange, but I don't remember which.