I want to do an Regex-Search in a document by using a IReplacingCallback in backward direction. Usually it works fine, but a specific document leads to arbitrary search order.
So I provided a testcase using two documents. The first document is the complex one delivering arbitrary order. The second one ist just a Copy/Paste-As-Ascii of the first document. The ordering is fine.
using Aspose.Words;
using Aspose.Words.Replacing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Generator.Tests
{
///
/// Searching a string in two documents (direction backward)
/// Document FindTest1.docx is using a lot of tables. The search-string is found in arbitrary ordering (=> bug??)
/// Document FindTest2.docx ist a Copy/PasteAsAscii-Copy of the first document. The search-string is found in descending order
///
/// Compiled Using DotNetFramework 4.5.1
/// Using Aspose.Word Version 16.8.0.0, Runtime v4.0.30319
///
/// Assuming: Search-Direction does not work in table (complex) structures
///
[TestClass]
public class AsposeGeneratorBugTest
{
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
const string licenseFile = “Aspose.Total.lic”;
new Aspose.Words.License().SetLicense(licenseFile);
}
///
/// For Document FindText1.docx
/// Searching all “CP_Bote” Strings in Document direction Backward
/// Expecting: Matching-Runs are found from back to front
///
[TestMethod]
public void FindTest1()
{
var doc = new Document(“d:\temp\FindTest1.docx”);
var replaceOptions = new FindReplaceOptions(FindReplaceDirection.Backward);
var evaluator = new RegexSkipEvaluator(); // just searching and collecting results
replaceOptions.ReplacingCallback = evaluator;
var nameRegex = new Regex(Regex.Escape(“CP_Bote”));
doc.Range.Replace(nameRegex, “”, replaceOptions);
// Find String
var result = evaluator.NodeResult.Select(n => n.PositionInDocument).ToList();
// Check that result ist sorted descending
var sortedResult = result.OrderByDescending(x => x).ToList();
Assert.IsTrue(result.SequenceEqual(sortedResult));
}
///
/// For Document FindText2.docx
/// Searching all “CP_Bote” Strings in Document direction Backward
/// Expecting: Matching-Runs are found from back to front
///
[TestMethod]
public void FindTest2()
{
var doc = new Document(“d:\temp\FindTest2.docx”);
var replaceOptions = new FindReplaceOptions(FindReplaceDirection.Backward);
var evaluator = new RegexSkipEvaluator(); // just searching and collecting results
replaceOptions.ReplacingCallback = evaluator;
var nameRegex = new Regex(Regex.Escape(“CP_Bote”));
doc.Range.Replace(nameRegex, “”, replaceOptions);
// Find String
var result = evaluator.NodeResult.Select(n => n.PositionInDocument).ToList();
// Check that result ist sorted descending
var sortedResult = result.OrderByDescending(x => x).ToList();
Assert.IsTrue(result.SequenceEqual(sortedResult));
}
}
///
/// Result Structure
///
public class SkipResult
{
public string Value { get; set; }
public Node MatchNode { get; set; }
public int PositionInDocument { get; set; }
}
///
/// Just collecting the Matches found by Regex
///
public class RegexSkipEvaluator : IReplacingCallback
{
public List NodeResult = new List();
public ReplaceAction Replacing(ReplacingArgs args)
{
var skipResult = new SkipResult
{
Value = args.Match.Value,
MatchNode = args.MatchNode,
PositionInDocument = args.MatchNode.Document.GetChildNodes(NodeType.Run, true)
.IndexOf(args.MatchNode)
};
NodeResult.Add(skipResult);
return ReplaceAction.Skip;
}
}
}