1
votes

Is it possible to duplicate a word document element with OpenXML without having any issues of "duplicate id" ?

Actually, to duplicate, I clone the elements inside the body and append the cloned elements in the body. But if any of the element have an ID, I'm having errors when I open the document in word.

Here is an example of error from OpenXML validator :

  • [60] Description="Attribute 'id' should have unique value. Its current value 'Rectangle 11' duplicates with others."

And here is my code :

        Document document = wordDocument.MainDocumentPart.Document;
        Body body = document.Body;
        IEnumerable<OpenXmlElement> elements = ((Body)body.CloneNode(true)).Elements();

        foreach (var element in elements)
        {
            OpenXmlElement e = (OpenXmlElement)element.CloneNode(true);

            body.AppendChild(e);              
        }
2

2 Answers

1
votes

You can't just copy elements with an id, you have to duplicate Parts too (search OpenXmlPart for more informations).

You can do this by combining functions AddPart() and GetIdOfPart() (accessible from MainDocumentPart)

First try: when you have an element with an id, use AddPart(OpenXmlPart part) to add the element part and retrieve the new generated id of the part with GetIdOfPart(OpenXmlPart part)

After that, you can replace in your cloned OpenXmlElement the id by the new one

Second try: or you could imagine an other way like:

  • Check highest id of existing parts (and save it)
  • Clone all parts from the start and choose yourself the id (by adding the highest saved id)
  • When you copy each element and find an id, add the saved highest id to match with the new part

I hope one of this way will help you, but in any case you will need to clone parts

0
votes

DocIO is a .NET class library that can read, write and render Microsoft Word documents. Using DocIO, you can clone the elements such as paragraph, table, text run or the entire document and append it where you need.

The whole suite of controls is available for free (commercial applications also) through the community license program if you qualify. The community license is the full product with no limitations or watermarks.

Herewith we have a given simple example code snippet which clone all the paragraphs and tables in the document body and append them at the end of the same document.

using Syncfusion.DocIO.DLS;

namespace DocIO_Clone
{
class Program
{
    static void Main(string[] args)
    {
        using (WordDocument document = new WordDocument(@"InputWordFile.docx"))
        {
            int sectionCount = document.Sections.Count;
            for (int i = 0; i < sectionCount; i++)
            {
                IWSection section = document.Sections[i];
                int entityCount = section.Body.ChildEntities.Count;
                for (int j = 0; j < entityCount; j++)
                {
                    IEntity entity = section.Body.ChildEntities[j];
                    switch(entity.EntityType)
                    { 
                        case EntityType.Paragraph:
                            IWParagraph paragraph = entity.Clone() as IWParagraph;
                            document.LastSection.Body.ChildEntities.Add(paragraph);
                            break;
                        case EntityType.Table:
                            IWTable table = entity.Clone() as IWTable;
                            document.LastSection.Body.ChildEntities.Add(table);
                            break;

                    }
                }
            }
            document.Save("ResultDocument.docx");
        }
    }
}
}

For further information, please refer our help documentation

Note: I work for Syncfusion