Deleting project files

Hi,

is there any way to delete a project file programatically? I have not found any related method in the API.

Thanks,

Tamas

Parents
  • Hi Tamas,

    You can load the project using FileBasedProject class and then call Delete() method.

    Romulus Crisan | Translation Productivity Development Manager | SDL | (twitter) @cromica_82 | (blog) http://www.romuluscrisan.com/

  • Hi,

    Sorry, I was not clear, I mean to delete a ProjectFile (a translatable or a reference file), not the sdlproj file itself.

    Tamas

  • Hi,

    Up on this one.

    I found a workaround, but it's definitely not straightforward: you delete the LanguageFile node using the Id (I used XPathDocument, and the XPath expression "//LanguageFile[@Guid='" + TargetLanguageFile.Id + "']", then physically deleting said file from the disk using System.IO.File.Delete(TargetLanguageFile.LocalFilePath);

    Whole code looks like this:

    XmlDocument pfile = new XmlDocument();
    pfile.Load(project.FilePath);
    XPathNavigator pnav = pfile.CreateNavigator();
    XPathExpression xpr = pnav.Compile(@"//LanguageFile[@Guid='" + tfiles[incr].Id + "']");
    XPathNodeIterator iterator = pnav.Select(xpr);
    foreach (XPathNavigator node in pnav.Select(xpr))
    {
        node.DeleteSelf();
    }
    pfile.Save(project.FilePath);
    File.Delete(tfiles[incr].LocalFilePath);

    Loop as you want to retrieve the file, it's entirely up to you. Note: "project" is the FileBasedProject, and tfiles[] is the project.TargetLanguageFiles().

    Careful though, as you will need to reload your FileBasedProject and not use any existing instance (everything is kept in memory, so changes made using XMLDocument will be overwritten.

    But it would be great if we could have a simple method to delete files/folders, or restrict CopyToTargetLanguages to specified languages only...

    Thanks,

    Sylvain

  • Thanks Sylvain,

    in the meantime I came to the same solution, this really works.

    Regards,

    Tamas

  • Hi,
    I tried to edit xml to removed unwanted files in project and save it. How can we reload FileBasedProject via API ? It seems that SDL trados studio need to be closed to reload updated project file.
  • Hello, SDL, any news on this?!
    It's actually quite common situation that client sends language-specific source files.
    And it's VERY annoying to either create a separate project for each language, or have to manually delete unwanted files from target languages in Studio GUI because there is no way to remove files from project via API :(
  • Hi Evzen,

    I have just had to struggle with this myself and found a comparatively simple solution. Yes, unfortunately one has to manipulate the project file XML directly. before you do that, just call the current ProjectsController and close the project:

    project.Save();
    var path = project.FilePath;

    var controller = SdlTradosStudio.Application.GetController<ProjectsController>();
    controller.Close(project);

    Have your code to manipulate the project file XML follow this.

    Edit: Here is some code I use to do this, maybe it will help you too.

    I have created a class to hold all necessary info about the nodes that shall be deleted:

    public class Deletable
    {
        public Deletable() { }
        public XmlNode Node { get; set; }
        public XmlNode Parent { get; set; }
        public string PhysicalPath { get; set; }
    }

    Also, in this project the source-language for us is always German, so that is hard-coded. The translation files all have the same naming convention "translations_xx-XX.xml" with "xx-XX" being the rfc 5646 language code (e.g. de-DE). Feel free to use and adjust to your own needs:

    //...

    XmlDocument pfile = new XmlDocument();
    pfile.Load(pfad);

    foreach (var tl in tLangs)
    {
        var fil = $"translations_{tl}.ggt";
        var filNodes = pfile.SelectNodes($"//ProjectFile[@Name='{fil}']");
        foreach (XmlNode node in filNodes)
        {
            var langFiles =
                node.SelectNodes(
                    $"./LanguageFiles/LanguageFile[@LanguageCode !='{tl}' and @LanguageCode !='de-DE']");
            var deleteThese = (from XmlNode subnode in langFiles
                let relPfad = subnode.SelectSingleNode("FileVersions/FileVersion").Attributes.GetNamedItem("PhysicalPath").Value
                let filpfad = Path.Combine(studioPfad, relPfad)
                select new Deletable
                {
                    Node = subnode,
                    Parent = subnode.ParentNode,
                    PhysicalPath = filpfad
                }).ToList();
            foreach (var delItem in deleteThese)
            {
                try
                {
                    File.Delete(delItem.PhysicalPath);
                    delItem.Parent.RemoveChild(delItem.Node);
                }
                catch (Exception ex)
                {
                    using (var sw = new StreamWriter(Path.Combine(studioPfad, "errors.log"), true))
                    {
                        sw.WriteLine("Error while deleting nodes from XML: {0}", ex.Message);
                    }
                }
            }
        }
    }

    pfile.Save(path);

    project = new FileBasedProject(path);

    To continue work on your project via API. It is also helpful to add a line

    controller.RefreshProjects();

    at the end of your code to make sure your newly edited project is visible in the projects view.

     

    Best regards,

    Andreas

Reply
  • Hi Evzen,

    I have just had to struggle with this myself and found a comparatively simple solution. Yes, unfortunately one has to manipulate the project file XML directly. before you do that, just call the current ProjectsController and close the project:

    project.Save();
    var path = project.FilePath;

    var controller = SdlTradosStudio.Application.GetController<ProjectsController>();
    controller.Close(project);

    Have your code to manipulate the project file XML follow this.

    Edit: Here is some code I use to do this, maybe it will help you too.

    I have created a class to hold all necessary info about the nodes that shall be deleted:

    public class Deletable
    {
        public Deletable() { }
        public XmlNode Node { get; set; }
        public XmlNode Parent { get; set; }
        public string PhysicalPath { get; set; }
    }

    Also, in this project the source-language for us is always German, so that is hard-coded. The translation files all have the same naming convention "translations_xx-XX.xml" with "xx-XX" being the rfc 5646 language code (e.g. de-DE). Feel free to use and adjust to your own needs:

    //...

    XmlDocument pfile = new XmlDocument();
    pfile.Load(pfad);

    foreach (var tl in tLangs)
    {
        var fil = $"translations_{tl}.ggt";
        var filNodes = pfile.SelectNodes($"//ProjectFile[@Name='{fil}']");
        foreach (XmlNode node in filNodes)
        {
            var langFiles =
                node.SelectNodes(
                    $"./LanguageFiles/LanguageFile[@LanguageCode !='{tl}' and @LanguageCode !='de-DE']");
            var deleteThese = (from XmlNode subnode in langFiles
                let relPfad = subnode.SelectSingleNode("FileVersions/FileVersion").Attributes.GetNamedItem("PhysicalPath").Value
                let filpfad = Path.Combine(studioPfad, relPfad)
                select new Deletable
                {
                    Node = subnode,
                    Parent = subnode.ParentNode,
                    PhysicalPath = filpfad
                }).ToList();
            foreach (var delItem in deleteThese)
            {
                try
                {
                    File.Delete(delItem.PhysicalPath);
                    delItem.Parent.RemoveChild(delItem.Node);
                }
                catch (Exception ex)
                {
                    using (var sw = new StreamWriter(Path.Combine(studioPfad, "errors.log"), true))
                    {
                        sw.WriteLine("Error while deleting nodes from XML: {0}", ex.Message);
                    }
                }
            }
        }
    }

    pfile.Save(path);

    project = new FileBasedProject(path);

    To continue work on your project via API. It is also helpful to add a line

    controller.RefreshProjects();

    at the end of your code to make sure your newly edited project is visible in the projects view.

     

    Best regards,

    Andreas

Children
No Data