XLIFF Filter: referents are not found when empty targets are processed after a subfiltered source

Issue #998 resolved
Denis Konovalyenko created an issue

Consider an XLIFF document with an empty target below:

<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns:of="http://okapiframework.org" xmlns:ofe="okapi-framework:xliff-extensions"
       xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:m="http://www.memsource.com/mxlf/2.0"
       version="1.2" m:version="2.3" m:level="1">
    <file source-language="en" target-language="fr" datatype="x-test" original="file.ext">
        <header>
            <m:in-ctx-preview-skel><![CDATA[<p>CDATA in header</p>]]></m:in-ctx-preview-skel>
        </header>
        <body>
            <trans-unit id="1">
                <source><![CDATA[<p>CDATA in source & &amp;</p>]]></source>
                <target xml:lang="fr"></target>
            </trans-unit>
        </body>
    </file>
</xliff>

If allowEmptyTargets parameter is set to false and cdataSubfilter is equal to okf_html, then <target xml:lang="fr">-ERR:REF-NOT-FOUND-</target> is produced on merge.

In more details, the net.sf.okapi.filters.xliff.XLIFFSkeletonWriter#getContent method fallbacks to source:

TextContainer trgCont = tu.getTarget(locToUse);
if ( trgCont == null || trgCont.isEmpty()) {
   if (params.getAllowEmptyTargets()) {
      // OLD (we were missing the segments): trgCont = new TextContainer(); // Empty target
      // We need to copy the source segments and empty them
      trgCont = tu.createTarget(locToUse, true, TextContainer.COPY_SEGMENTATION);
   }
   else {
      // If there is no target available
      // We fall back to source
      trgCont = srcCont;
   }        
}

but the source content has a code reference, which referent was used at the time of the source processing… Thus, the referent is not available and we end up with writing the -ERR:REF-NOT-FOUND- in net.sf.okapi.common.skeleton.GenericSkeletonWriter#expandCodeContent method:

...
        while ( (marker = TextFragment.getRefMarker(tmp)) != null ) {
            int start = (Integer)marker[1];
            int end = (Integer)marker[2];
            String propName = (String)marker[3];
            IReferenceable ref = getReference((String)marker[0]);
            if ( ref == null ) {
                logger.warn("Reference '{}' not found.", marker[0]);
                tmp.replace(start, end, "-ERR:REF-NOT-FOUND-");
            }
...

Comments (4)

  1. Log in to comment