Hi,
I have a document with multiple text placeholders.
I want to replace all placeholders by passing a map having key value pairs.
As of now i could find the way to replace text using below code
Document doc = new Document(getMyDir() + "Document.doc");
doc.getRange().replace(“sad”, “bad”, false, true);
I don’t want iterate this code for multiple replacement, rather I want to pass
a map as a parameter to replace all matching keys with values.
eg : doc.getRange().replace(myMap, false, true); or something similar
I would like to know if there is any method provide by aspose word to fulfil
this requirement.
Thanks
Hi Sumit,
Thanks for your inquiry. Unfortunately, Aspose.Words does not support the requested feature at the moment. We have logged this feature request as WORDSNET-14134 in our issue tracking system. You will be notified via this forum thread once this feature is available.
We apologize for your inconvenience.
Thanks Tahir,
I would like to know if any functionality available to pass the XML as input to replace all the matching placeholders in document.
Note: the place holders does not follow any convention i.e. placeholders are free form texts which matches the XML tag name.
Hi Sumit,
Thanks for your inquiry. Could you please share complete detail of your use case along with input template document and xml that you want to pass to Range.Replace method? We will update the issue detail accordingly.
Hi Tahir,
The sample XML will look like below.
<?xml version="1.0" encoding="UTF-8"?>
<letter_id>1234526</letter_id>
<case_id>789456</case_id>
<template_id>53262356</template_id>
<case_activity_id>12345</case_activity_id>
<case_pending_status>Print</case_pending_status>
<p_name>Sumit</p_name>
<p_age>25</p_age>
<p_logo>image.png</p_logo>
And the template (.dot) file will have the following place holders
p_name letter_id case_activity_id
p_age case_id case_pening_status
p_logo template_id
Hi Sumit,
Thanks for sharing the detail.
In your case we suggest you please use mail merge feature of Aspose.Words. Please read the following article about mail merge. You need to replace p_name, letter_id etc. with mail merge fields in your template document.
About Mail Merge
How to Mail Merge from XML using IMailMergeDataSource
You may use LINQ Reporting Engine to replace the mentioned text (place holders) with values from XML. Please read about template syntax and Linq reporting engine API from following links. Hope this helps you.
Template Syntax
LINQ Reporting Engine API
Hi Tahir,
Thanks for your reply. As per mail merge feature of Aspose words, we can replace the placeholders having below format
<<p_name>>
<<letter_id>>
But in our case the placeholders would be free form text.
p-name
letter_id
(without any angle bracket).
Any solution for this scenario?
Thanks,
Sumit
Hi Sumit,
Thanks for your inquiry. You need to modify your template document. Please insert the mail merge field e.g. <> at the place of “p_name”. The mail merge field’s codes are { MERGEFIELD p_name * MERGEFORMAT } for this field.
If you don’t want to modify your document, you can use find and replace feature of Aspose.Words.
Hi,
Wanted to check, if this feature ( WORDSNET-14134) already available in the new versions? If yes, please guide me the docs.
Thanks,
NM
@nileshmishra The implementation of the feature has been postponed, but you can easily achieve this using the currently available features and IReplaceingCallback. For example see the following code:
Dictionary<string, string> keyValyePairs = new Dictionary<string, string>();
keyValyePairs.Add("key1", "First Replacement");
keyValyePairs.Add("key2", "Second Replacement");
keyValyePairs.Add("key3", "Third Replacement");
Document doc = new Document(@"C:\Temp\in.docx");
FindReplaceOptions opt = new FindReplaceOptions();
opt.ReplacingCallback = new ReplacingCallback(keyValyePairs);
// Create regular expression to match all keys.
string regexString = String.Join("|", keyValyePairs.Select(x => Regex.Escape(x.Key)));
Regex regx = new Regex(regexString);
doc.Range.Replace(regx, "", opt);
doc.Save(@"C:\Temp\out.docx");
public class ReplacingCallback : IReplacingCallback
{
public ReplacingCallback(Dictionary<string, string> keyValyePairs)
{
mKeyValyePairs = keyValyePairs;
}
public ReplaceAction Replacing(ReplacingArgs args)
{
if (mKeyValyePairs.ContainsKey(args.Match.Value))
{
args.Replacement = mKeyValyePairs[args.Match.Value];
return ReplaceAction.Replace;
}
return ReplaceAction.Skip;
}
private Dictionary<string, string> mKeyValyePairs;
}
Thanks for the solution. I tried to implement this with Java. If my key in the Map is starting with $ the callback was never invoked & if it started with [ then the args.getMatch().group() always gave a single letter but not the entire key. Curious to know how the callback works.
@nileshmishra Here is a Java equivalent of the code:
HashMap<String, String> keyValyePairs = new HashMap<String, String>();
keyValyePairs.put("$key1", "First Replacement");
keyValyePairs.put("$key2", "Second Replacement");
keyValyePairs.put("$key3", "Third Replacement");
Document doc = new Document("C:\\Temp\\in.docx");
FindReplaceOptions opt = new FindReplaceOptions();
opt.setReplacingCallback(new ReplacingCallback(keyValyePairs));
// Create regular expression to match all keys.
String regexString = "";
for (String key : keyValyePairs.keySet())
regexString += Pattern.quote(key) + "|";
regexString = regexString.substring(0, regexString.length() - 1);
Pattern regx = Pattern.compile(regexString);
doc.getRange().replace(regx, "", opt);
doc.save("C:\\Temp\\out.docx");
public static class ReplacingCallback implements IReplacingCallback
{
public ReplacingCallback(HashMap<String, String> keyValyePairs)
{
mKeyValyePairs = keyValyePairs;
}
public int replacing(ReplacingArgs args)
{
if (mKeyValyePairs.containsKey(args.getMatch().group()))
{
args.setReplacement(mKeyValyePairs.get(args.getMatch().group()));
return ReplaceAction.REPLACE;
}
return ReplaceAction.SKIP;
}
private HashMap<String, String> mKeyValyePairs;
}
If you still have difficulties, please provide your input document and key/replacement set here for testing. We will check on our side and provide you more information.
testing.docx (12.5 KB)
This is the map via which i’m making the replacement

I have used the same code as show above:
My args should be keys of my map ideally, tho i see it’s not the same case.
2024-04-01 21:26:19 [http-nio-8080-exec-2] [818181881] INFO s.c.p.d.util.ReplacingCallback:21 - Args are: $name
2024-04-01 21:26:22 [http-nio-8080-exec-2] [818181881] INFO s.c.p.d.util.ReplacingCallback:21 - Args are: $name
2024-04-01 21:26:22 [http-nio-8080-exec-2] [818181881] INFO s.c.p.d.util.ReplacingCallback:21 - Args are: $name
Output:
Could you help me to understand, why this is happening & how can we fix this ?
@nileshmishra Please try using the following regular expression "\\$[\\w]+":
HashMap<String, String> keyValyePairs = new HashMap<String, String>();
keyValyePairs.put("$name", "nilesh");
keyValyePairs.put("$nameOfPerson", "Marsh");
keyValyePairs.put("$nameOfVisitor", "everyone");
Document doc = new Document("C:\\Temp\\in.docx");
FindReplaceOptions opt = new FindReplaceOptions();
opt.setReplacingCallback(new ReplacingCallback(keyValyePairs));
Pattern regx = Pattern.compile("\\$[\\w]+");
doc.getRange().replace(regx, "", opt);
doc.save("C:\\Temp\\out.docx");