Hi,
is there any way to delete a project file programatically? I have not found any related method in the API.
Thanks,
Tamas
Hi,
is there any way to delete a project file programatically? I have not found any related method in the API.
Thanks,
Tamas
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 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
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