Nested track changes exported incorrectly in SDLXLIFF export

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • None
    • Affects Version/s: None
    • Component/s: Export

      Problem

      When exporting translations with track changes back to SDLXLIFF, segments that contain nested track changes (for instance, an addition or styling edit nested inside another addition) along with inline formatting tags produce corrupted XML or fail export validation.

      What was happening:

      1. Nested revisions were mangled: TrackChangesFormatter assumed that any element inside a revision block (<mrk>) was an internal formatting tag (<div>). When a revision was nested inside another revision, the formatter treated the inner <mrk> container as a regular tag and deleted/overwrote it, losing parts of the tracked changes.
      2. Invalid tag wrapping: When an opening formatting tag (like <g id="1086">) was opened before a tracked change and closed inside it without containing any visible text, the exporter attempted to wrap the entire tracked change or left unclosed tags at the end of the segment. In SDLXLIFF, such empty boundary tags must be self-closing (e.g. <g id="1086" sdl:end="false"/>).
      3. Closing tags in addition marks were missed: The logic that tracked whether an external tag had been closed within a revision block was only checking deletion blocks, missing tags that were closed inside added revisions.

      Solution

      Update TrackChangesFormatter to properly handle nested revision scopes and empty structure tags:

      1. Recursive Mark Processing: Extract processMrkNode() to recursively traverse nested <mrk> elements so each revision layer processes its own tags without overwriting child revisions.
      2. Self-closing Boundary Tags: Add hasNonWhitespaceBetween() to detect when an unclosed tag has no visible text before the next revision block. In these cases, it generates a self-closing marker tag (<g id="..." sdl:end="false"/>) instead of incorrectly wrapping the subsequent revision.
      3. Universal Scope Tracking: Track tags closed across all revision marks (both additions and deletions) to ensure matching open tags in the body are cleanly closed before track changes start.
      4. Test Coverage: Add and verify real-world test case Segment from real world 4 in TrackChangesFormatterTest.php.

            Assignee:
            Sanya Mikhliaiev
            Reporter:
            Sanya Mikhliaiev
            None
            None
            Thomas Lauria
            NO-FRONTEND-TESTING NEEDED
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              None
              None