mp2
May 13, 2022, 7:03pm
1
I am updating document control tags and in some scenarios we are getting ‘Cannot add a node before/after itself’ but it works fine if we add a space before the tag.
I am curious to know why would it throw an error and why would it fix if we add a space.
I have attached the sample word document
failing-reviewmemo-prod.docx (39.2 KB)
using aspose-words-21.6.0.jdk17.jar
@mp2 Could you please provide code that will allow us to reproduce the problem? I trued with this code and SDT is updated correctly:
Document doc = new Document("C:\\Temp\\in.docx");
Iterable<StructuredDocumentTag> sdts = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true);
for (StructuredDocumentTag sdt : sdts)
{
if (sdt.getSdtType() == SdtType.RICH_TEXT)
{
sdt.removeAllChildren();
if (sdt.getLevel() == MarkupLevel.BLOCK)
{
Paragraph para = new Paragraph(doc);
para.appendChild(new Run(doc, "This is updated text"));
sdt.appendChild(para);
}
else if (sdt.getLevel() == MarkupLevel.INLINE)
{
sdt.appendChild(new Run(doc, "This is updated text"));
}
}
}
doc.save("C:\\Temp\\out.docx");
mp2
May 14, 2022, 2:19pm
3
Here you go:
public static void updateDocumentTagFields(Document doc, Map<String, String> props) throws Exception {
String sdtTitle = "";
// update the form fields
NodeCollection<StructuredDocumentTag> contentControlCollection = doc
.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true);
for (StructuredDocumentTag sdt : contentControlCollection) {
sdtTitle = sdt.getTitle();
HeaderFooter headerFooter = (HeaderFooter) sdt.getAncestor(NodeType.HEADER_FOOTER);
if (props.containsKey(sdtTitle) && props.get(sdtTitle) != null) {
try {
switch (sdt.getSdtType()) {
case SdtType.PLAIN_TEXT:
updateRichText(doc, sdt, props.get(sdtTitle), (headerFooter == null) ? false : true);
break;
case SdtType.RICH_TEXT:
updateRichText(doc, sdt, props.get(sdtTitle), (headerFooter == null) ? false : true);
break;
case SdtType.CHECKBOX:
updateCheckBox(doc, sdt, props.get(sdtTitle));
break;
}
} catch (Exception e) {
throw new Exception("Error occured while updating DocumentTagField( " + sdtTitle + " = "
+ props.get(sdtTitle) + " ) " + e.getMessage());
}
}
}
}
public static void updateCheckBox(Document doc, StructuredDocumentTag sdt, String txtVal) throws Exception {
if (txtVal.equalsIgnoreCase("true"))
sdt.setChecked(true);
else
sdt.setChecked(false);
}
public static void updateTextNode(Document doc, StructuredDocumentTag sdt, String txtVal) throws Exception {
sdt.removeAllChildren();
Run run = new Run(doc, txtVal);
sdt.appendChild(run);
}
public static void updateRichText(Document doc, StructuredDocumentTag sdt, String txtVal, boolean isHeaderPresent)
throws Exception {
if (isHeaderPresent) {
// Get the first Run of text you want to keep formatting of
Run firstRun = (Run) sdt.getChildNodes(NodeType.RUN, true).get(0);
// Remove all other nodes
if (firstRun != null)
for (Node node : (Iterable<Node>) sdt.getChildNodes(NodeType.ANY, true))
if (node != firstRun)
node.remove();
// Update the text of first Run
firstRun.setText(txtVal);
} else {
Run run = new Run(doc);
run.setText(txtVal);
if (sdt.getLevel() == MarkupLevel.INLINE) {
sdt.removeAllChildren();
sdt.getChildNodes().add(run);
} else if (sdt.getLevel() == MarkupLevel.BLOCK) {
sdt.removeAllChildren();
Paragraph para = (Paragraph) sdt.appendChild(new Paragraph(doc));
para.getRuns().add(run);
sdt.getChildNodes().add(para);
} else if (sdt.getLevel() == MarkupLevel.CELL) {
if (sdt.getFirstChild().getNodeType() == NodeType.CELL) {
Cell cell = (Cell) sdt.getFirstChild();
cell.removeAllChildren();
cell.ensureMinimum();
Paragraph para = ((Cell) sdt.getFirstChild()).getFirstParagraph();
para.getRuns().add(run);
}
}
}
}
@maaaruf Thank you for additional information. There is a mistake in your code. See the following snippet:
} else if (sdt.getLevel() == MarkupLevel.BLOCK) {
sdt.removeAllChildren();
Paragraph para = (Paragraph) sdt.appendChild(new Paragraph(doc));
para.getRuns().add(run);
sdt.getChildNodes().add(para);
You add the paragraph to SDT here:
Paragraph para = (Paragraph) sdt.appendChild(new Paragraph(doc));
and again here:
sdt.getChildNodes().add(para);
You should modify this code like the following:
} else if (sdt.getLevel() == MarkupLevel.BLOCK) {
sdt.removeAllChildren();
Paragraph para = (Paragraph) sdt.appendChild(new Paragraph(doc));
para.appendChild(run);
mp2
May 15, 2022, 12:57pm
5
thank you very much Alexey…that worked…you guys are best!
1 Like