Custom XML mapped by Aspose.Word removed after editing document

Hi,
I have a problem with mapping custom xml in my worddocument.
Everything works fine at first, im creating a StructuredDocumentTag, adding my custom XML-file and then mapping the specified field to the StructuredDocumentTag.

At this point everything works, the Tag is inserted correct and the XML is mapped and displaying the correct text.
However, if i open the document, change something in the text inside the document (not in the content control) and save it, the mapped XML disappears. The custom XML-file is still there but the mapping is somehow removed.

KE055_omappad_som_ska_mappas.docx (67.2 KB)

Code:

StructuredDocumentTag Sdttext = new StructuredDocumentTag(document, SdtType.RichText, MarkupLevel.Block);
Sdttext.RemoveAllChildren();

var xml = File.ReadAllText(PathToCustomXmlFile);
CustomXmlPart customXmlPart = document.CustomXmlParts.Add(Guid.NewGuid().ToString("B"), xml);
                            
Sdttext.XmlMapping.SetMapping(customXmlPart,"CustomXpath" ,"CustomPrefixMapping");
Sdttext.Tag = "Tag";
Sdttext.Title = "Title";
Doc.InsertAfter(Sdttext, somenode);
document.Save("SaveFileToPath.docx");

Do you have any ideas?

Best regards Tim

@Timpa_elite I see the mapping is not set in the document you have attached. But I cannot reproduce the problem on my side. I have generated document with StructuredDocumentTag and XML Mapping using the following code:

Document doc = new Document();
CustomXmlPart xmlPart = doc.CustomXmlParts.Add(Guid.NewGuid().ToString("B"), "<root><text>Hello, World!</text></root>");

StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.RichText, MarkupLevel.Block);
doc.FirstSection.Body.AppendChild(sdt);

sdt.XmlMapping.SetMapping(xmlPart, "/root[1]/text[1]", "");

// Save the document to disk.
doc.Save(@"C:\Temp\out.docx");

Then I edited the output document in MS Word and checked XML Mapping - ut us still there:

<w:sdt>
	<w:sdtPr>
		<w:id w:val="938833094"/>
		<w:placeholder>
			<w:docPart w:val="DefaultPlaceholder_22675703"/>
		</w:placeholder>
		<w15:dataBinding w:xpath="/root[1]/text[1]" w:storeItemID="{AB4AFDDC-1E6C-472D-BA6C-7CD553B5FFFE}" w16sdtdh:storeItemChecksum="jaUYAA=="/>
	</w:sdtPr>
	<w:sdtEndPr/>
	<w:sdtContent>
		<w:p w14:paraId="199EB951" w14:textId="628196CB" w:rsidR="002C5F2A" w:rsidRDefault="00BA3593">
			<w:r>
				<w:t>Hello, World!</w:t>
			</w:r>
		</w:p>
	</w:sdtContent>
</w:sdt>

Could you please attach your source document, sample XML and code? We will check the issue with your files and provide you more information. Also, proles attach DOCX document produced by Aspose.Words on your side before editing it in MS Word.

Hi,

Source document: KE055_omappad_som_ska_mappas.docx (70.2 KB)

Mapped document that’s working: Testa_mappa_en_gammal ke055.docx (67.1 KB)

Mapped document after adding text in document: Testa_mappa_en_gammal ke055.docx (71.4 KB)

SampleXml:

<DOCX_SETTINGS xmlns="http://tempuri.org/">
	<TOINSERTINDOCXFILE>
		<DOCX_DATA>
			<DATANODES>
				<DATAFIELD wordcustomcontrolname="W3D3_Diarienummer">|TSTR_DNO|</DATAFIELD>
			</DATANODES>
		</DOCX_DATA>
	</TOINSERTINDOCXFILE>
</DOCX_SETTINGS>

Sourcode:

using (MemoryStream documentStream = new MemoryStream(file))
{
    Document document = new Document(documentStream);
    HeaderFooterCollection headers = document.FirstSection.HeadersFooters;
    foreach (var header in headers)
    {
        var test = (Aspose.Words.HeaderFooter)header;
        var children = test.GetChildNodes(NodeType.Paragraph, true);
        for (int i = 0; i < children.Count; i++)
        {
            var child = (Paragraph)children[i];
            if (child.Range.Text.Contains("|TSTR_DNO|"))
            {

                StructuredDocumentTag Sdttext =
                    new StructuredDocumentTag(document, SdtType.RichText, MarkupLevel.Block);
                Sdttext.RemoveAllChildren();

                var xml = File.ReadAllText(
                    "customXml");
                CustomXmlPart customXmlPart =
                    document.CustomXmlParts.Add(Guid.NewGuid().ToString("B"), xml);
                Sdttext.XmlMapping.SetMapping(customXmlPart,
                    "/ns0:DOCX_SETTINGS[1]/ns0:TOINSERTINDOCXFILE[1]/ns0:DOCX_DATA[1]/ns0:DATANODES[1]/ns0:DATAFIELD[1]",
                    "xmlns:ns0='http://tempuri.org/'");

                Sdttext.Tag = "W3D3_Diarienummer";
                Sdttext.Title = "Diarienummer";

                test.InsertAfter(Sdttext, child);

                children.Remove(child);
                document.Save("Testa_mappa_en_gammal ke055.docx");
            }
        }
    }
}

@Timpa_elite Thank you for additional information. Could you please also let me know how you edit the document generated by Aspose.Words? I tried editing your document using MS Word 2019 and after saving XML mapping is preserved.

<w:sdtPr>
	<w:alias w:val="Diarienummer"/>
	<w:tag w:val="W3D3_Diarienummer"/>
	<w:id w:val="93260578"/>
	<w:placeholder>
		<w:docPart w:val="DefaultPlaceholder_22675703"/>
	</w:placeholder>
	<w15:dataBinding w:prefixMappings="xmlns:ns0='http://tempuri.org/'" w:xpath="/ns0:DOCX_SETTINGS[1]/ns0:TOINSERTINDOCXFILE[1]/ns0:DOCX_DATA[1]/ns0:DATANODES[1]/ns0:DATAFIELD[3]" w:storeItemID="{A21B9638-414D-44CB-9518-A2412228E906}" w16sdtdh:storeItemChecksum="TXQsPA=="/>
</w:sdtPr>

Hi,
Thanks for answer.
Can you confirm that the mapping has been removed from the edited document i uploaded?

The way i edit is simply by opening the document, and add some text inside, close and save.
Please see the document title on the mapped document that is working vs the mapped document that i have edited. I changed the title from “Yttrande” to “Yttrande test”.

@Timpa_elite Yes, XML mapping is lost in the document you have attached:

<w:sdtPr>
	<w:alias w:val="Diarienummer"/>
	<w:tag w:val="W3D3_Diarienummer"/>
	<w:id w:val="1650898376"/>
	<w:placeholder>
		<w:docPart w:val="DefaultPlaceholder_22675703"/>
	</w:placeholder>
</w:sdtPr>

Do you edit the document in MS Word?

Yes, i open the document, saved by the code, in Word 2016:

document.Save("Testa_mappa_en_gammal ke055.docx");

@Timpa_elite Unfortunately, I cannot reproduce the problem on my side. Is there a chance that some macro is executed upon saving the document on your side and it removed XML mapping from the document.
Could you please try to open/edit/save this document: in.docx (20.1 KB)?
It contains two Content Controls with XML Mapping created in MS Word.

Hi,
The XML mapping did not get removed when i edited your document.
The document doesn’t seem to contain any macros, according to this code:

var hasMacros = document.HasMacros;

Can you reproduce my issue by editing the document i uploaded containing the XML mapping?

Update:
I tried to insert the Content Control and Xml mapping inside the body of the document instead of in the header and that seems to work. Is there something wrong with inserting content controls in the header of the document?

Also, if i add Tag and Title values and insert and map the Content control to the body of the document the mapping gets removed after editing, but not if i leave the fields blank, weird?

@Timpa_elite Yes, I have tested with your document. I opened document you have generated on your side in MS Word, edited it and save. XML mapping is preserved.
I have tried to generate a simple document with SDT in the document’s header:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);

CustomXmlPart xmlPart = doc.CustomXmlParts.Add(Guid.NewGuid().ToString("B"), "<root><text>Hello, World!</text></root>");

StructuredDocumentTag sdt = new StructuredDocumentTag(doc, SdtType.PlainText, MarkupLevel.Inline);
builder.InsertNode(sdt);

sdt.XmlMapping.SetMapping(xmlPart, "/root[1]/text[1]", "");

// Save the document to disk.
doc.Save(@"C:\Temp\out.docx");

out.docx (12.0 KB)
Edited it in MS Word and still mapping is preserted:
out_edited.docx (21.9 KB)

The macros can be in the default document template. Unfortunately, I have no more ideas why the problem might occur on your side.

Hi,
I tried to create a new document and copy the content to it.
In the new document i can insert, map the xml and edit the document without the mapping getting removed.
It seems you were right about there being something wrong with the original document. I suppose it’s quite easy to just create a new document with Aspose and clone the contents from the original.
Thank you for the help!

@Timpa_elite Yes, this might be the reason of the problem. But the strange thing is that I cannot reproduce the problem even with your original document.
Anyways it is perfect that you can work the problem around.

I think i have narrowed down the problem.
I made it work with my original document, it seems that if i add a “Tag” and “Title” to the StructuredDocumentTag the mapping gets lost after editing the document.

Okej, so i think i figured it out.
I did everything in the wrong order.
It works now that i:

  1. Create SDT.
  2. Insert it into document.
  3. Map XML.
  4. Add Title/Tag

@Timpa_elite It is perfect that you managed to figure out where the problem is. But this is really strange because order of the operations does not matter - SDT is written the same. For example the following code:

StructuredDocumentTag sdt1 = new StructuredDocumentTag(doc, SdtType.PlainText, MarkupLevel.Inline);
builder.InsertNode(sdt1);
sdt1.XmlMapping.SetMapping(xmlPart, "/root[1]/text[1]", "");
sdt1.Title = "Title 1";
sdt1.Tag = "test";

builder.Writeln();

StructuredDocumentTag sdt2 = new StructuredDocumentTag(doc, SdtType.PlainText, MarkupLevel.Inline);
sdt2.Title = "Title 2";
sdt2.Tag = "test";
sdt2.XmlMapping.SetMapping(xmlPart, "/root[1]/text[1]", "");
builder.InsertNode(sdt2);

Will produce the following XML in docx document:

<w:p>
	<w:sdt>
		<w:sdtPr>
			<w:alias w:val="Title 1" />
			<w:tag w:val="test" />
			<w:id w:val="2103295408" />
			<w:placeholder>
				<w:docPart w:val="DefaultPlaceholder_22675703" />
			</w:placeholder>
			<w:dataBinding w:xpath="/root[1]/text[1]" w:storeItemID="{70b392fd-1b92-4bba-8c29-2d0a0808c7be}" />
			<w:text />
		</w:sdtPr>
		<w:sdtContent>
			<w:r>
				<w:t>Hello, World!</w:t>
			</w:r>
		</w:sdtContent>
	</w:sdt>
</w:p>
<w:p>
	<w:sdt>
		<w:sdtPr>
			<w:alias w:val="Title 2" />
			<w:tag w:val="test" />
			<w:id w:val="792352430" />
			<w:placeholder>
				<w:docPart w:val="DefaultPlaceholder_22675703" />
			</w:placeholder>
			<w:dataBinding w:xpath="/root[1]/text[1]" w:storeItemID="{70b392fd-1b92-4bba-8c29-2d0a0808c7be}" />
			<w:text />
		</w:sdtPr>
		<w:sdtContent>
			<w:r>
				<w:t>Hello, World!</w:t>
			</w:r>
		</w:sdtContent>
	</w:sdt>
</w:p>

As you can see SDT has absolutely the same structure and should be processed the same in MS Word.