0
\$\begingroup\$

I implemented a function to check a MS Word document is contain a given word or not. The function will return true if filePath is contain word. Otherwise it will return false.

This is my solution based on Aspose framework. Is there any better solution?

public class FindContentOfWordDoc
{
    public bool FindContent(string filePath, string content)
    {
        var doc = new Document(filePath);

        var findReplaceOptions = new FindReplaceOptions
        {
            ReplacingCallback = new FindCallBack(),
            Direction = FindReplaceDirection.Backward
        };

        var regex = new Regex(content, RegexOptions.IgnoreCase);
        doc.Range.Replace(regex, "", findReplaceOptions);

        return (findReplaceOptions.ReplacingCallback as FindCallBack)?.IsMatch ?? false;
    }

    private class FindCallBack : IReplacingCallback
    {
        public bool IsMatch { get; private set; }
        ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
        {
            IsMatch = true;
            return ReplaceAction.Stop;
        }
    }
}

Thanks!

\$\endgroup\$
4
\$\begingroup\$

Some quick remarks:

  • FindContentOfWordDoc is a bad class name, in the first place because it contains a verb. Please follow the Microsoft rules.

  • While this code only does a search, it is peppered with names that refer to "find and replace". This makes it hard to understand. I assume this must be due to Aspose, so perhaps this is inevitable, but then perhaps you could add some comments to explain why you implemented it this way.

    Are you certain this is the best way to execute a search? I find it odd that you would need to "abuse" the "find and replace" functionality; it seems odd that Aspose would include that functionality yet not a "find" on its own.

  • You don't check content: is this function only intended for single word queries, or also for combinations of words? And why not check if the user actually entered a search term, in order to avoid invoking the callback etc. on a null or an empty string?

\$\endgroup\$
0
\$\begingroup\$

It looks rather complicated to me, but it seems that Aspose doesn't have a Find api, so you'll have to go with the Find-replace option.


You can consider to use the COM-interop, but it's very slow:

bool FindContent(string path, string content)
{
  Application application = new Application();
  application.Visible = false;
  Document document = application.Documents.Open(path);
  Range range = document.Range(Type.Missing, Type.Missing);
  bool result = range.Find.Execute(content);

  range = null;
  document.Close(false);
  document = null;
  application.Quit(false);
  application = null;

  return result;
}

Alternatively you can use Open XML SDK:

bool FindContent(string path, string content)
{
  using (WordprocessingDocument doc = WordprocessingDocument.Open(path, false))
  {
    MainDocumentPart mainPart = doc.MainDocumentPart;

    return mainPart.Document.InnerText.Contains(content)
      || mainPart.HeaderParts.Any(hp => hp.Header.InnerText.Contains(content))
      || mainPart.FooterParts.Any(fp => fp.Footer.InnerText.Contains(content));
  }
}

It's fast but can be rather complicated to understand and work with and it only supports the docx-format - not the .doc-format. I'm not sure how it behave if the document is encrypted/password protected or if the above example covers all user text, but it's a place to start.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.