Replacing a text with multiple words in Apache POI XWPF not working - org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
<p>Trying to replace text with multiple words spread across different runs in a paragraph using sample provided by @Thierry Bodhuin below, however, it throws  below exception:</p>

<pre><code>Exception in thread "main" org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl.isSetRsidDel(Unknown Source)
at org.apache.poi.xwpf.usermodel.XWPFParagraph.getText(XWPFParagraph.java:221)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:60)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:52)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:37)
at com.db.a.WordExtractReplaceFormat.main(WordExtractReplaceFormat.java:114)
</code></pre>

<p>*Code snippet from this answer [<a href="https://stackoverflow.com/questions/22268898/replacing-a-text-in-apache-poi-xwpf/41135914#41135914]">Replacing a text in Apache POI XWPF</a> by **Thierry Bodhuin</p>

<pre><code>import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

public class WordExtractReplaceFormat {

private static Map&lt;Integer, XWPFRun&gt; getPosToRuns(XWPFParagraph paragraph) {
    int pos = 0;
    Map&lt;Integer, XWPFRun&gt; map = new HashMap&lt;Integer, XWPFRun&gt;(10);
    for (XWPFRun run : paragraph.getRuns()) {
        String runText = run.text();
        if (runText != null) {
            for (int i = 0; i &lt; runText.length(); i++) {
                map.put(pos + i, run);
            }
            pos += runText.length();
        }
    }
    return (map);
}

public static &lt;V&gt; void replace(XWPFDocument document, Map&lt;String, V&gt; map) throws FileNotFoundException, IOException {
    List&lt;XWPFParagraph&gt; paragraphs = document.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs) {
        replace(paragraph, map);
    }
    String filePath = "C:\\test-1.docx";
    saveWord(filePath, document);
}

public static &lt;V&gt; void replace(XWPFDocument document, String searchText, V replacement) {
    List&lt;XWPFParagraph&gt; paragraphs = document.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs) {
        replace(paragraph, searchText, replacement);
    }
}

private static &lt;V&gt; void replace(XWPFParagraph paragraph, Map&lt;String, V&gt; map) {
    for (Map.Entry&lt;String, V&gt; entry : map.entrySet()) {
        replace(paragraph, entry.getKey(), entry.getValue());
    }
}

public static &lt;V&gt; void replace(XWPFParagraph paragraph, String searchText, V replacement) {
    boolean found = true;
    while (found) {
        found = false;
        int pos = paragraph.getText().indexOf(searchText);
        if (pos &gt;= 0) {
            found = true;
            Map&lt;Integer, XWPFRun&gt; posToRuns = getPosToRuns(paragraph);
            XWPFRun run = posToRuns.get(pos);
            XWPFRun lastRun = posToRuns.get(pos + searchText.length() - 1);
            int runNum = paragraph.getRuns().indexOf(run);
            int lastRunNum = paragraph.getRuns().indexOf(lastRun);
            String texts[] = replacement.toString().split("\n");
            run.setText(texts[0], 0);
            XWPFRun newRun = run;
            for (int i = 1; i &lt; texts.length; i++) {
                newRun.addCarriageReturn();
                newRun = paragraph.insertNewRun(runNum + i);
                /*
                    We should copy all style attributes
                    to the newRun from run
                    also from background color, ...
                    Here we duplicate only the simple attributes...
                 */
                newRun.setText(texts[i]);
                newRun.setBold(run.isBold());
                newRun.setCapitalized(run.isCapitalized());
                // newRun.setCharacterSpacing(run.getCharacterSpacing());
                newRun.setColor(run.getColor());
                newRun.setDoubleStrikethrough(run.isDoubleStrikeThrough());
                newRun.setEmbossed(run.isEmbossed());
                newRun.setFontFamily(run.getFontFamily());
                newRun.setFontSize(run.getFontSize());
                newRun.setImprinted(run.isImprinted());
                newRun.setItalic(run.isItalic());
                newRun.setKerning(run.getKerning());
                newRun.setShadow(run.isShadowed());
                newRun.setSmallCaps(run.isSmallCaps());
                newRun.setStrikeThrough(run.isStrikeThrough());
                newRun.setSubscript(run.getSubscript());
                newRun.setUnderline(run.getUnderline());
            }
            for (int i = lastRunNum + texts.length - 1; i &gt; runNum + texts.length - 1; i--) {
                paragraph.removeRun(i);
            }
        }
    }
}

public static void main(String[] args) throws FileNotFoundException, IOException {
    XWPFDocument docx;
    Map&lt;String, String&gt; keyValue = new TreeMap&lt;&gt;();
    keyValue.put("$&lt;[Member] [Manager] [Officer]&gt;", "Member Only");
    keyValue.put("${Lawyer_Name}", "Lawyer Name Updated with Actual");
    keyValue.put("${Place_Holder_Key}", "Place_Holder_value");

    WordExtractReplaceFormat wexrf = new WordExtractReplaceFormat();
    docx = new XWPFDocument(new FileInputStream("C:\\test.docx"));
    wexrf.replace(docx, keyValue);
}

private static void saveWord(String filePath, XWPFDocument doc) throws FileNotFoundException, IOException{
    FileOutputStream out = null;
    try{
        out = new FileOutputStream(filePath);
        doc.write(out);
    }
    finally{
        out.close();
    }
}
</code></pre>

<p>}</p>

<p>**Code fails at this line -  int pos = paragraph.getText().indexOf(searchText);</p>