Hi,
I am writing to you about a problem we encountered in working with MSO Word documents (docx format) using the Aspose Words v21.10 library for Java.
Specifically, when we access a specific DateSDT and change its value, and then save the document as new one, in the new, target document, the change is not made.
I am enclosing the source file as well as the test code for reproducing the mentioned issue.
Best regards!
Nenad
report.zip (93.3 KB)
@zpredojevic Your code is not quite correct. The following line of code is incorrect:
NodeCollection dateSDTs = document.getChildNodes(SdtType.DATE, true);
getChildNodes
method accepts NodeType, not SdtType.
The code for updating Date SDTs should look like the following:
Document doc = new Document("C:\\Temp\\in.docx");
// Get SDTs
Iterable<StructuredDocumentTag> sdts = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true);
// Loop through the SDTs and update date SDT.
for (StructuredDocumentTag sdt : sdts)
{
if (sdt.getSdtType() == SdtType.DATE)
sdt.setFullDate(new Date());
}
doc.save("C:\\Temp\\out.docx");
1 Like
@alexey.noskov
I understand your point of view, however, it cannot be applied as such in this situation.
Using your approach, the second DateSDT object in the iterator is exactly the one I sent you with the test when reporting the issue (DateSDT containing “Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021”) which can be seen by calling the getText() method for the given StructuralDocumentTag instance (the second one in the iterator you submitted).
The reason why the provided solution cannot be applied is that as a new value of the given DateSDT we want to set “New_Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021” for which we do not have the possibility to call a method like setText() for the given StructuralDocumentTag instance, and the constructor of the Date class does not allow the same.
This is the reason for applying the approach by which we reported the issue.
Best regards!
Nenad
@zpredojevic If you need to set some custom text as value of Date SDT, you can simply add this text as child nodes to the SDT. For example:
Document doc = new Document("C:\\Temp\\in.docx");
// Get SDTs
Iterable<StructuredDocumentTag> sdts = doc.getChildNodes(NodeType.STRUCTURED_DOCUMENT_TAG, true);
// Loop through the SDTs and update date SDT.
for (StructuredDocumentTag sdt : sdts)
{
if (sdt.getSdtType() == SdtType.DATE)
{
System.out.println(sdt.toString(SaveFormat.TEXT).trim());
sdt.removeAllChildren();
if (sdt.getLevel() == MarkupLevel.INLINE)
{
sdt.appendChild(new Run(doc, "This is Some custom text"));
}
else if ((sdt.getLevel() == MarkupLevel.BLOCK))
{
Paragraph p = new Paragraph(doc);
p.appendChild(new Run(doc, "This is Some custom text"));
sdt.appendChild(p);
}
}
}
doc.save("C:\\Temp\\out.docx");
@alexey.noskov
Thanks for the help, but the problem we have is still present.
Whether we use the setter to change the value of the Run object of a specific SDT instance, or whether we replace the existing Run object with a new one with the appropriate content, after calling the save() method on the Document instance, the change does not remain (while all other changes in document are kept properly - not shown by the test).
In the attachment, I am sending you the same source file and two more test codes (one uses a setter, the other a constructor) where you can see the exactly same behavior - the original content of DateSDT is properly read, changing the content and reading it after reloading the given DateSDT (before calling save() method over the Document instance) works fine, while after saving the document either over the same Document instance or over a new one (target document), the changed content of the DateSDT cannot be read (it is not retained after the execution of the save() method).
I hope we will overcome this issue soon.
Nenad
report2.zip (94.4 KB)
@zpredojevic Thank you for additional information. SDT in your document are gets value from custom XML, so changing it’s value does not have any effect.
I have simplified the document so that it contain only one SDT: in.docx (43.2 KB)
You can remove xml mapping, in this case the value will be stored in the SDT itself:
Document document = new Document("C:\\Temp\\in.docx");
// fetching the target DateSDT (source doc)
StructuredDocumentTag dateSDT = (StructuredDocumentTag)document.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true);
assertEquals("Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021", dateSDT.getText());
// Remove mapping
dateSDT.getXmlMapping().delete();
// Remove old content.
dateSDT.removeAllChildren();
// Add new text
dateSDT.appendChild(new Run(document, "New_Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021"));
// fetching the target DateSDT (source doc) after change
dateSDT = (StructuredDocumentTag)document.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true);
// proving that the change is done (DateSDT has new value)
assertEquals("New_Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021", dateSDT.getText());
// saving the document as the new one (target document)
document.save("C:\\Temp\\out.docx");
// fetching the target DateSDT (same Document instance)
dateSDT = (StructuredDocumentTag)document.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true);
// proving that the change is present
assertEquals("New_Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021", dateSDT.getText());
// instantiation of the target document
document = new Document("C:\\Temp\\out.docx");
// fetching the target date SDT content (target doc - new Document instance)
dateSDT = (StructuredDocumentTag)document.getChild(NodeType.STRUCTURED_DOCUMENT_TAG, 0, true);
// proving that the content of target date SDT (target doc) has new value
// date SDT content is not changed, but it should be
assertEquals("New_Fund Managers: Frank Thormann, Alex Tedder | Fund update: April 2021", dateSDT.getText());
@alexey.noskov
We menaged to make workaround with removing XML mapping. Thanks for help!
Best regards!
Nenad
1 Like