Project Automation API from template, TM error

When Project Automation API example BatchAnalyzer, based on a template (sdltpl), I get the error:
The combination of Uri and State properties for the main translation providers should be unique within the list of entries.

The template only has one TM listed, but it doesn't have a State attribute:
<MainTranslationProviderItem Uri="sdltm.file:///PATH-TO-TM/TM-FILENAME.sdltm" Enabled="true" />

I then added State="unique", and it processes:
<MainTranslationProviderItem Uri="sdltm.file:///PATH-TO-TM/TM-FILENAME.sdltm" Enabled="true" State="unique"/>

However, the sdlproj file then ends up with two memories, one with Concordance set to true and the other set to false.

<CascadeEntryItem PerformConcordanceSearch="true" Penalty="0" PerformUpdate="true" PerformNormalSearch="true">
      <MainTranslationProviderItem Uri="sdltm.file:///PATH-TO-TM/TM-FILENAME.sdltm" State="unique" Enabled="true" />
      <ProjectTranslationProviderItem Uri="sdltm.file:///Tm/en-GB/PROJECT-TM.sdltm" Enabled="true" />
</CascadeEntryItem>

<CascadeEntryItem PerformConcordanceSearch="false" Penalty="0" PerformUpdate="true" PerformNormalSearch="true">
      <MainTranslationProviderItem Uri="sdltm.file:///PATH-TO-TM/TM-FILENAME.sdltm" Enabled="true" />
      <ProjectTranslationProviderItem Uri="sdltm.file:///Tm/en-GB/PROJECT-TM.sdltm" Enabled="true" />
</CascadeEntryItem>

- Note: the second TM does not have the State attribute.

Question is, I cannot see a state setting within Trados TM Settings, so how does this attribute set assigned automatically, or is there a way around this problem?

Thanks in advance

  • Hi Samuel,
    Not sure if that will answer your question, but let me explain how do i use templates during prep. I do develop automation for large LSP, where we do have hundreds of language combinations for our client:-).

    So i do have a master templates, and when they are used i do created this function to change source, target language code:

    private static void ModifyProjectTemplate(TradosWorkQueue tradosWorkQueue)
    {
    XmlDocument doc = new XmlDocument();
    doc.XmlResolver = null;
    doc.Load(tradosWorkQueue.ProjectTemplate);
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
    nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
    string xpath1 = "/ProjectTemplate/LanguageDirections/LanguageDirection";

    XmlNodeList nodes = doc.SelectNodes(xpath1);
    if (nodes.Count > 1)
    {
    for (int i = nodes.Count - 1; i <= 0; i--)
    {
    if (i > 0)
    {
    nodes[i].ParentNode.RemoveChild(nodes[i]);
    }
    else
    {
    nodes[i].Attributes["TargetLanguageCode"].Value = tradosWorkQueue.TargetTradosCode;
    nodes[i].Attributes["SourceLanguageCode"].Value = tradosWorkQueue.SourceTradosCode;
    }
    }
    }
    else
    {
    XmlNode node = nodes[0];

    node.Attributes["TargetLanguageCode"].Value = tradosWorkQueue.TargetTradosCode;
    node.Attributes["SourceLanguageCode"].Value = tradosWorkQueue.SourceTradosCode;
    }
    XmlNode termbasenodes = doc.SelectSingleNode("/ProjectTemplate/TermbaseConfiguration");
    termbasenodes.ChildNodes[0].ChildNodes[0].InnerText = tradosWorkQueue.SourceTradosCode;
    termbasenodes.ChildNodes[1].ChildNodes[0].InnerText = tradosWorkQueue.TargetTradosCode;
    doc.Save(tradosWorkQueue.ProjectTemplate);
    }


    Then, to clear all template memories i do that:

    TranslationProviderConfiguration config = p.GetTranslationProviderConfiguration(trgLanguage);
    config.Entries.Clear();

    Then i do that to add translation memories:

    DataTable dt_memories = analyze_q.DataUtils.RetrieveDataTable(sql);
    TranslationProviderCascadeEntry[] tmEntries =
    new TranslationProviderCascadeEntry[dt_memories.Rows.Count + 1];
    tmEntries[0] = new TranslationProviderCascadeEntry(tm_file, true, true, true, 0);



    for (int i = 1; i <= dt_memories.Rows.Count; i++)
    {
    TradosMemory mem = new TradosMemory();

    DataRow row = dt_memories.Rows[i - 1];

    mem.MemoryID = int.Parse(row["memory_id"].ToString());
    mem.Load();
    tmEntries[i] = new TranslationProviderCascadeEntry(mem.MemoryFile, mem.Update.Value,
    mem.Search.Value, mem.Concordance.Value, mem.Penalty.Value);
    }

    for (int i = 0; i < tmEntries.Length; i++)
    {


    config.OverrideParent = true;
    config.Entries.Add(tmEntries[i]);

    }



    Also, you don't really need to have tm in the template. I'm not sure if this has answered your question, but i hope it did helped you to understand how you can work around templates.

    EDIT: Emoticons.... bulbs should be [ i ]

  • Hi Wojciec,

    Thanks for the reply, I understand what you're saying.

    My question though, is whether or not you can use TM file(s) within the template, without the State attribute?

    And why, after adding the required State attribute, does the SDL Project file (sdlproj), contain a (almost) duplicate TM?

    If the API allows you to reference a template, that contains TM file(s), why would it require an attribute that does not get assigned by default?

    Unless I am missing something obvious, it seems a bit of an unnecessary workaround.

    Thanks.

  • In your case the problem is caused by the fact that the Batch Analyzer app is also adding the TM that you specify to the project. If this is already in the template then this will result in duplicate entries hence the error from your initial post. If you look at the code in the Batch Analyzer in the file ProjectCreator.cs at line 69 you will see the AddTm method. 

    In conclusion you can definitely use TM file(s) within the template. 

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

  • Hi Romulus,

    Thanks for the reply and explaining the issue.

    It looks like it's working well now.

    Thanks a million.

    Sam