1

I hope this is the right forum to ask this question. If it is not, please redirect me to a more suitable forum.

I am trying to understand the format of a Qt Linguist TS file. I have modified a file and when I try to open it I get the error message "Duplicate messages found in ...". The file contains indeed one context with two messages that have

  • the same source
  • a location with the same file name but different line numbers
  • different translation

Here is the source code of a minimal file that gives this error:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="es">
<context>
    <name>MyContext</name>
    <message>
        <location filename="../../../../../MyFile.cpp" line="605"/>
        <source>Delete</source>
        <translatorcomment>Menu option</translatorcomment>
        <translation type="unfinished">&amp;Borrar</translation>
    </message>
    <message>
        <location filename="../../../../../MyFile.cpp" line="1572"/>
        <source>Delete</source>
        <translation>Eliminar</translation>
    </message>
</context>
</TS>

To my knowledge, each message is identified by context, source and location so this should not be a problem because the line numbers are different. Notice also that you cannot combine the two message elements into one, because they contain different translation texts.

So it is not clear to me what can cause the error message. I am using Qt version 4.6.2. I have looked in the following documents: Qt Linguist Manual: Translator, Qt Linguist Manual: Programmers, Linguist TS file format, but in none of them I have found the information I am looking for, namely how each message is identified and what could cause the error message in Qt Linguist.

If you do not know the answer to this question, a link to further, more detailed information on the TS format would also be helpful.

UPDATE

I have found out that by using the optional tag TS/context/message/comment it is possible to have different translation texts for the same context/message/source, e.g.

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="es">
<context>
    <name>MyContext</name>
    <message>
        <location filename="../../../../../MyFile.cpp" line="605"/>
        <source>Delete</source>
        <comment>Comment 1</comment>
        <translatorcomment>Menu option</translatorcomment>
        <translation type="unfinished">&amp;Borrar</translation>
    </message>
    <message>
        <location filename="../../../../../MyFile.cpp" line="1572"/>
        <source>Delete</source>
        <comment>Comment 2</comment>
        <translation>Eliminar</translation>
    </message>
</context>
</TS>

The above file can be opened without errors.

This seems to solve my problem but it would be good to have some precise documentation about this format.

Giorgio
  • 5,023
  • 6
  • 41
  • 71
  • Qt 4.6.2. I will add this information to the question. – Giorgio Jan 12 '12 at 10:44
  • Do you feel comfortable using XML technology? – menjaraz Jan 12 '12 at 10:52
  • Yes, I have written several tools for reading and writing XML files. I would not define myself as an _advanced user_ of XML but I have worked quite a lot with it. I need to know how a message element is identified inside a TS/context element in a Qt Linguist file. – Giorgio Jan 12 '12 at 10:55
  • Being a valid XML document, your modified TS file can be validated against the DTD given in [Linguist TS file format](http://developer.qt.nokia.com/doc/qt-4.8/linguist-ts-file-format.html) link you provided. Btw, you can help other people willing to answer your question by providing a complete snippet of the modification you've introduced to a supposedly valid TS file. – menjaraz Jan 12 '12 at 11:47
  • Can it be that the DTD found on that page serves only as a reference? When I try to validate the DTD itself (e.g. on http://www.validome.org/grammar/validate/) I get an error at line 29 (it is on line 31 with the DTD for Qt version 4.6): <!ELEMENT extra-* %evilstring; >. xmllint gives the same error message on the DTD and cannot validate the XML file. – Giorgio Jan 12 '12 at 12:15

2 Answers2

3

The error message reported by Qt linguist is meaningfull.

Try this modified version of your TS file:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>

<TS version="2.0" language="es">
  <context>
    <name>MyContext</name>
        <message>
            <location filename="../../../../../MyFile.cpp" line="605"/>
            <source>Delete</source>
            <translatorcomment>Menu option</translatorcomment>
            <translation type="unfinished">&amp;Borrar</translation>
        </message>
    </context>
  <context>
    <name>MyOtherContext</name>
        <message>
            <location filename="../../../../../MyFile.cpp" line="1572"/>
            <source>Delete</source>
            <translation>Eliminar</translation>
        </message>
    </context>
</TS>

Duplicates are identified by context (i.e. MyContext vs. MyOtherContext) and source (Delete).

Edit:

I have scrutinized Qt Linguist's source code. As far as I can tell it never make use of ts.dtd for validation purpose, everything is hardcoded (See the TSReader class in ts.cpp).

The moral is: you can do every manipulation you want if and only if the resulting ts file can be loaded again by Qt Linguist and accepted by lupdate (to resync the application).

Jonathan Cross
  • 675
  • 8
  • 17
menjaraz
  • 7,551
  • 4
  • 41
  • 81
  • You are correct, but it is be possible to have the same context, the same source, and different translation texts. I have found out that there is an optional comment tag: TS/context/message/comment. If two messages have a different comment, it seems that they are acceptable. At least I do not get the error message. – Giorgio Jan 12 '12 at 13:48
  • Thanks a lot for taking the time to look into the source code! Can you move the above comment to your answer? Then I can accept it. – Giorgio Jan 12 '12 at 14:29
1

The complete lookup key for a translation is

Context + source string and, when present, disambiguation string

see http://qt-project.org/doc/qt-4.8/i18n-source-translation.html#disambiguation

The disambiguation string is stored in the comment field since this was also, in older Qt versions, the way to insert a developer comment (it is still recognized as such by Qt Linguist and so is the new comment (extracomment in the .ts file see http://qt-project.org/doc/qt-4.8/i18n-source-translation.html#translator-comments)).

So, as you noticed, you can have two strings with the same context and source string as long as they have different disambiguation strings (or one of them has one and the other does not).

Puzzled
  • 29
  • 8