none
Handling Dangling CustomXMLPart when replacing CustomXML from a Word Template RRS feed

  • Question

  • I am creating a Word Template with a Custom XML part linked to content controls in my template. I then replace the Custom XML Part in my code using this code:

            protected void ReplaceCustomXML(string fileName, string customXML)
            {
                using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileName, true))
                {
                    MainDocumentPart mainPart = wordDoc.MainDocumentPart;
                    mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);
                    //Add a new customXML part and then add the content. 
                    CustomXmlPart customXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);//(<CustomXmlPart>();// AddNewPart<CustomXmlPart>();
                    //Copy the XML into the new part. 
                    using (StreamWriter ts = new StreamWriter(customXmlPart.GetStream())) ts.Write(customXML);
                }
            }
    

    My original custom XML is this:

    <Person>
     <Name>John Smith</Name>
     <Age>15</Age>
     <Phone>555-5555</Phone>
    </Person>

    My new custom XML is this:

    <Person>
     <Name>Jane Doe</Name>
     <Age>25</Age>
    </Person>

    Is there a way to not show the Phone number if it doesn't exist in the new XML? Right now it shows the Phone number that is set in the Word Template since it can't find a new phone number.

    Tuesday, January 3, 2017 5:18 PM

All replies

  • Hi,

    We could retrieve the dataBinding for each content control, get its XPath and then check if there is node in the new XML using XPath. Then you could decide to remove the content control or change its text.

    E.g.

       private static void retrieveXPath(string fileName,string customXML)
            {
                using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileName, false))
                {
                    MainDocumentPart mainPart = wordDoc.MainDocumentPart;
                    Body body = mainPart.Document.Body;
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(customXML);
                    XmlNode root = doc.DocumentElement;
    
                    foreach (SdtBlock sdtBlock in body.Descendants<SdtBlock>())
                    {
                        DataBinding dataBinding = sdtBlock.Descendants<DataBinding>().FirstOrDefault();
                        string xPath = dataBinding.XPath;
                        Console.WriteLine(xPath);
    
                        XmlNode node = root.SelectSingleNode(xPath);
                        if (node !=null)
                        {
                            Console.WriteLine(node.InnerXml);
                        }                                      
                    }
                }
    
            }
    

    Regards,

    Celeste



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 4, 2017 8:21 AM
    Moderator
  • Thanks, that is a good idea. I will have to play around with this code. It didn't quite work because it didn't go into the for loop.
    Monday, January 9, 2017 4:15 PM
  • Hi,

    Do you find any solution for your issue?

    I suggest you check its node by Open XML SDK Tool or changing the file extension into .ZIP. You could download Open XML SDK Tool from https://www.microsoft.com/en-us/download/details.aspx?id=30425

    Besides, using Open XML SDK Tool, you could generate the code you want by comparing the files:

    1. Create two documents with one is original file and one is the target file;

    2. Use Open XML SDK 2.5 productivity Tool for Microsoft Office

    3. Click the Compare Files, generate the code, and then you could get the code what you want

    Regards,

    Celeste


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, January 13, 2017 10:00 AM
    Moderator