public void InsertDocument(DocX remote_document, bool append = true)
{
// We don't want to effect the origional XDocument, so create a new one from the old one.
XDocument remote_mainDoc = new XDocument(remote_document.mainDoc);
XDocument remote_footnotes = null;
if (remote_document.footnotes != null)
remote_footnotes = new XDocument(remote_document.footnotes);
XDocument remote_endnotes = null;
if (remote_document.endnotes != null)
remote_endnotes = new XDocument(remote_document.endnotes);
// Remove all header and footer references.
remote_mainDoc.Descendants(XName.Get("headerReference", w.NamespaceName)).Remove();
remote_mainDoc.Descendants(XName.Get("footerReference", w.NamespaceName)).Remove();
// Get the body of the remote document.
XElement remote_body = remote_mainDoc.Root.Element(XName.Get("body", w.NamespaceName));
// Every file that is missing from the local document will have to be copied, every file that already exists will have to be merged.
PackagePartCollection ppc = remote_document.package.GetParts();
List<String> ignoreContentTypes = new List<string>
{
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
"application/vnd.openxmlformats-package.core-properties+xml",
"application/vnd.openxmlformats-officedocument.extended-properties+xml",
"application/vnd.openxmlformats-package.relationships+xml"
};
List<String> imageContentTypes = new List<string>
{
"image/jpeg",
"image/jpg",
"image/png",
"image/bmp",
"image/gif",
"image/tiff",
"image/icon",
"image/pcx",
"image/emf",
"image/wmf"
};
// Check if each PackagePart pp exists in this document.
foreach (PackagePart remote_pp in ppc)
{
if (ignoreContentTypes.Contains(remote_pp.ContentType) || imageContentTypes.Contains(remote_pp.ContentType))
continue;
// If this external PackagePart already exits then we must merge them.
if (package.PartExists(remote_pp.Uri))
{
PackagePart local_pp = package.GetPart(remote_pp.Uri);
switch (remote_pp.ContentType)
{
case "application/vnd.openxmlformats-officedocument.custom-properties+xml":
merge_customs(remote_pp, local_pp, remote_mainDoc);
break;
// Merge footnotes (and endnotes) before merging styles, then set the remote_footnotes to the just updated footnotes
case "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":
merge_footnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes);
remote_footnotes = footnotes;
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":
merge_endnotes(remote_pp, local_pp, remote_mainDoc, remote_document, remote_endnotes);
remote_endnotes = endnotes;
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":
merge_styles(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes, remote_endnotes);
break;
// Merge styles after merging the footnotes, so the changes will be applied to the correct document/footnotes
case "application/vnd.ms-word.stylesWithEffects+xml":
merge_styles(remote_pp, local_pp, remote_mainDoc, remote_document, remote_footnotes, remote_endnotes);
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml":
merge_fonts(remote_pp, local_pp, remote_mainDoc, remote_document);
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":
merge_numbering(remote_pp, local_pp, remote_mainDoc, remote_document);
break;
}
}
// If this external PackagePart does not exits in the internal document then we can simply copy it.
else
{
var packagePart = clonePackagePart(remote_pp);
switch (remote_pp.ContentType)
{
case "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":
endnotesPart = packagePart;
endnotes = remote_endnotes;
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":
footnotesPart = packagePart;
footnotes = remote_footnotes;
break;
case "application/vnd.openxmlformats-officedocument.custom-properties+xml":
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":
stylesPart = packagePart;
using (TextReader tr = new StreamReader(stylesPart.GetStream()))
styles = XDocument.Load(tr);
break;
case "application/vnd.ms-word.stylesWithEffects+xml":
stylesWithEffectsPart = packagePart;
using (TextReader tr = new StreamReader(stylesWithEffectsPart.GetStream()))
stylesWithEffects = XDocument.Load(tr);
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml":
fontTablePart = packagePart;
using (TextReader tr = new StreamReader(fontTablePart.GetStream()))
fontTable = XDocument.Load(tr);
break;
case "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":
numberingPart = packagePart;
using (TextReader tr = new StreamReader(numberingPart.GetStream()))
numbering = XDocument.Load(tr);
break;
}
clonePackageRelationship(remote_document, remote_pp, remote_mainDoc);
}
}
foreach (var hyperlink_rel in remote_document.mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"))
{
var old_rel_Id = hyperlink_rel.Id;
var new_rel_Id = mainPart.CreateRelationship(hyperlink_rel.TargetUri, hyperlink_rel.TargetMode, hyperlink_rel.RelationshipType).Id;
var hyperlink_refs = remote_mainDoc.Descendants(XName.Get("hyperlink", w.NamespaceName));
foreach (var hyperlink_ref in hyperlink_refs)
{
XAttribute a0 = hyperlink_ref.Attribute(XName.Get("id", r.NamespaceName));
if (a0 != null && a0.Value == old_rel_Id)
{
a0.SetValue(new_rel_Id);
}
}
}
////ole object links
foreach (var oleObject_rel in remote_document.mainPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"))
{
var old_rel_Id = oleObject_rel.Id;
var new_rel_Id = mainPart.CreateRelationship(oleObject_rel.TargetUri, oleObject_rel.TargetMode, oleObject_rel.RelationshipType).Id;
var oleObject_refs = remote_mainDoc.Descendants(XName.Get("OLEObject", "urn:schemas-microsoft-com:office:office"));
foreach (var oleObject_ref in oleObject_refs)
{
XAttribute a0 = oleObject_ref.Attribute(XName.Get("id", r.NamespaceName));
if (a0 != null && a0.Value == old_rel_Id)
{
a0.SetValue(new_rel_Id);
}
}
}
foreach (PackagePart remote_pp in ppc)
{
if (imageContentTypes.Contains(remote_pp.ContentType))
{
merge_images(remote_pp, remote_document, remote_mainDoc, remote_pp.ContentType);
}
}
int id = 0;
var local_docPrs = mainDoc.Root.Descendants(XName.Get("docPr", wp.NamespaceName));
foreach (var local_docPr in local_docPrs)
{
XAttribute a_id = local_docPr.Attribute(XName.Get("id"));
int a_id_value;
if (a_id != null && int.TryParse(a_id.Value, out a_id_value))
if (a_id_value > id)
id = a_id_value;
}
id++;
// docPr must be sequential
var docPrs = remote_body.Descendants(XName.Get("docPr", wp.NamespaceName));
foreach (var docPr in docPrs)
{
docPr.SetAttributeValue(XName.Get("id"), id);
id++;
}
// Add the remote documents contents to this document.
XElement local_body = mainDoc.Root.Element(XName.Get("body", w.NamespaceName));
if (append)
local_body.Add(remote_body.Elements());
else
local_body.AddFirst(remote_body.Elements());
// Copy any missing root attributes to the local document.
foreach (XAttribute a in remote_mainDoc.Root.Attributes())
{
if (mainDoc.Root.Attribute(a.Name) == null)
{
mainDoc.Root.SetAttributeValue(a.Name, a.Value);
}
}
}