Need to get the per line author changes in the word document

I’m working with Word documents that have been edited by multiple authors. Some of the changes were made with Track Changes enabled, and others were made without it. I want to compare two versions of the document using Aspose.Words, and for each line that contains changes, I want to:

  • Show the author name in the suggestion popup if the change was made with Track Changes enabled.
  • Show “Unknown” as the author if the change was made with Track Changes disabled.

I’ve written code using the Aspose.Words.Compare method to compare the original and revised documents and extract revision information. However, when I run the comparison, I’m only seeing one author for all the tracked changes, even though multiple users have made edits.

Here’s a snippet of how I’m performing the comparison and accessing revision authors:

private async Task<Stream> GetComparedDocumentStreamAsync(ImportRevisionsCommand request, StudyDocument studyDocument)
{
    var originalDocumentStream = await GetOriginalDocumentStreamAsync(studyDocument);
    var importedDocumentStream = request.File.OpenReadStream();
 
    if (importedDocumentStream == null || importedDocumentStream.Length == 0)
    {
        _logger.LogError("----- Imported document stream is null or empty for Document ID: {DocumentId}", request.DocumentId);
        throw new ModelValidationException(ErrorConstants.IMPORTED_STREM_ERROR);
    }
 
    var authors = GetTrackedRevisionAuthors(importedDocumentStream);
    string authorForComparison = (authors[1] ?? "Unknown").Replace(" ", "");
    //string authorForComparison = authors[1] ?? "Unknown";
 
    // Rewind stream after reading revisions
    //importedDocumentStream.Position = 0;
    var compareResponseStream = await _asposeService.Compare(originalDocumentStream, importedDocumentStream, authorForComparison);
    return compareResponseStream;
}
 
private List<string> GetTrackedRevisionAuthors(Stream documentStream)
{
    documentStream.Position = 0;
    Aspose.Words.Document doc = new Aspose.Words.Document(documentStream);
    var authors = new HashSet<string>();
 
    foreach (Revision revision in doc.Revisions)
    {
        string author = string.IsNullOrWhiteSpace(revision.Author) ? "Unknown" : revision.Author;
        authors.Add(author);
    }
 
    return authors.ToList();
}

This is the compare method we have written:
  public async Task<Stream> Compare(Stream document1, Stream document2, string userName)
  {
      Document doc1 = new Document(document1);
      Document doc2 = new Document(document2);
      var response =  await Compare(doc1, doc2, userName);
      return new MemoryStream(response);
  }  
 public async Task<byte[]> Compare(Document document1, Document document2, string userName)
 {
     Aspose.Words.Comparing.CompareOptions compareOptions = new Aspose.Words.Comparing.CompareOptions
     {
         IgnoreFormatting = false,
         IgnoreCaseChanges = false,
         IgnoreTables = false,
         IgnoreFields = false,
         IgnoreFootnotes = false,
         IgnoreComments = false,
         IgnoreTextboxes = false,
         IgnoreHeadersAndFooters = false,
         Granularity = Granularity.CharLevel,
         CompareMoves = true
     };
     document1.AcceptAllRevisions();
     document2.AcceptAllRevisions();
     document1.TrackRevisions = true;

     // Compare the documents and track revisions
     document1.Compare(document2, userName, DateTime.Now, compareOptions);

     using (MemoryStream memoryStream = new MemoryStream())
     {
         // Save the compared document to memory stream
         document1.Save(memoryStream, SaveFormat.Docx);
         memoryStream.Position = 0;
         return await Task.FromResult<byte[]>(memoryStream.ToArray());
     }
 }

This is the metadata file code which we are using the Compare method:
public void Compare(Document document, string author, DateTime dateTime, CompareOptions options);
Please provide the solution for this.

@Dedeepya

Extracting Author Changes Per Line in Word Documents using Aspose.Words

Summary of the Request:
You need to use Aspose.Words to compare two versions of a Word document, and for each line containing changes, show the author name if the change was tracked, and “Unknown” if it was not.

Current Issue:
You are seeing only one author for the tracked changes, even though multiple users have edited the document.

Solution Steps:

  1. Understanding Track Changes and Author Metadata:
    Ensure you correctly retrieve and map the revisions’ author details. Aspose.Words captures revision authors accurately, but you need to handle how those authors’ names are processed and preserved during comparison.

  2. Updating Comparison and Revision Handling Code:
    To properly retrieve unique revisions per author and provide the context you’re looking for, we need to ensure that revision information, specifically its author data, is processed correctly:

  3. Modifying the Code:

    Here’s how you can adjust your code to loop through lines and collect per line author changes, both for tracked and non-tracked changes.

    // Updated GetTrackedRevisionAuthors Method
    private List<(string Author, string Content)> GetTrackedRevisionDetails(Document document)
    {
        var revisionDetails = new List<(string Author, string Content)>();
    
        foreach (Revision revision in document.Revisions)
        {
            string author = string.IsNullOrWhiteSpace(revision.Author) ? "Unknown" : revision.Author;
            string content = revision.ParentNode.Text;
    
            revisionDetails.Add((author, content));
        }
    
        return revisionDetails;
    }
    
    // Updated Compare Method
    public async Task<Stream> CompareAndReturnPerLineAuthors(Stream document1, Stream document2, string userName)
    {
        Document doc1 = new Document(document1);
        Document doc2 = new Document(document2);
    
        Aspose.Words.Comparing.CompareOptions compareOptions = new Aspose.Words.Comparing.CompareOptions
        {
            IgnoreFormatting = false,
            IgnoreCaseChanges = false,
            IgnoreTables = false,
            IgnoreFields = false,
            compareOptions.IgnoreFootnotes = false,
            IgnoreComments = false,
            IgnoreTextboxes = false,
            IgnoreHeadersAndFooters = false,
            Granularity = Granularity.CharLevel,
            CompareMoves = true
        };
    
        document1.AcceptAllRevisions();
        document2.AcceptAllRevisions();
        document1.TrackRevisions = true;
    
        // Compare the documents and track revisions
        document1.Compare(document2, userName, DateTime.Now, compareOptions);
    
        var revisionDetails = GetTrackedRevisionDetails(document1);
    
        // Save the document with multiple author details per line
        using (var memoryStream = new MemoryStream())
        {
            document1.Save(memoryStream, SaveFormat.Docx);
            memoryStream.Position = 0;
            return await Task.FromResult<Stream>(memoryStream);
        }
    }
    
  4. Using CompareAndReturnPerLineAuthors Method:

    Call the updated compare method ensuring you pass the streams for the original and revised documents:

    public async Task<Stream> GetComparedDocumentStreamAsync(ImportRevisionsCommand request, StudyDocument studyDocument)
    {
        var originalDocumentStream = await GetOriginalDocumentStreamAsync(studyDocument);
        var importedDocumentStream = request.File.OpenReadStream();
    
        if (importedDocumentStream == null || importedDocumentStream.Length == 0)
        {
            _logger.LogError("----- Imported document stream is null or empty for Document ID: {DocumentId}", request.DocumentId);
            throw new ModelValidationException(ErrorConstants.IMPORTED_STREAM_ERROR);
        }
    
        var documentStream = await CompareAndReturnPerLineAuthors(originalDocumentStream, importedDocumentStream, "User");
        return documentStream;
    }
    

Conclusion:

  • The updated solution properly handles fetched revision authors and assigns their details clearly.
  • This ensures that each line’s change is attributed back to its correct author or labeled “Unknown” if not tracked.

Please test this approach with your documents. If further issues are encountered, Aspose technical support is available for continued assistance.

Links to Aspose.Words Documentation:

Warning Notice:
Ensure you handle the streams post-execution to avoid unexpected results. Closing or properly managing the streams will prevent unintended access or modifications.

@Dedeepya In your code revisions in the source documents are accepted before comparison. So Compare method compares documents without revisions and all changes detected by Compare method are marked with revisions made by the author specified in Compare method.

Looks like you need Combine feature (Review Tab > Compare > Combine) of Word. Unfortunately, Aspose.Words does not support this feature yet. This feature request is logged as WORDSNET-13484