static XObject UpdateReferences([NotNull] XObject xObject, MappingSequence footnoteSequence) { switch (xObject) { case XAttribute a when a.Name == W + "id" && a.Parent?.Name == W + "footnoteReference": return(new XAttribute(a.Name, footnoteSequence.GetValue(a.Value))); case XAttribute a: return(new XAttribute(a.Name, a.Value)); case XElement e: return (new XElement( e.Name, e.Attributes().Select(x => UpdateReferences(x, footnoteSequence)), e.Nodes().Select(x => UpdateReferences(x, footnoteSequence)))); case XText t: return(new XText(t.Value)); default: return(xObject); } }
public static Footnotes Concat([NotNull] Footnotes first, [NotNull] Footnotes second) { if (first is null) { throw new ArgumentNullException(nameof(first)); } if (second is null) { throw new ArgumentNullException(nameof(second)); } Sequence idSequence = new Sequence("rId{0}"); MappingSequence footnoteSequence = new MappingSequence(); Package result = first._package.ToPackage(FileAccess.ReadWrite); if (result.PartExists(PartUri)) { result.DeletePart(PartUri); } PackagePart part = result.CreatePart(PartUri, ContentType); Dictionary <string, PackageRelationship> resources = new Dictionary <string, PackageRelationship>(); Dictionary <string, PackageRelationship> otherResources = new Dictionary <string, PackageRelationship>(); // For existing hyperlinks: recreate the relationship. foreach (HyperlinkInfo info in first.Hyperlinks) { resources[info.Id] = part.CreateRelationship(info.Target, info.TargetMode, HyperlinkInfo.RelationshipType, idSequence.NextValue()); } // For new hyperlinks: create the relationship. foreach (HyperlinkInfo info in second.Hyperlinks) { otherResources[info.Id] = part.CreateRelationship(info.Target, info.TargetMode, HyperlinkInfo.RelationshipType, idSequence.NextValue()); } XElement content = new XElement( first.Content.Name, Combine(first.Content.Attributes(), second.Content.Attributes()), first.Content.Nodes() .Select(x => UpdateResources(x, resources)) .Select(x => UpdateFootnotes(x, footnoteSequence)), second.Content .Nodes() .Select(x => UpdateResources(x, otherResources)) .Select(x => UpdateFootnotes(x, footnoteSequence))); content.WriteTo(part); PackagePart documentPart = result.GetPart(Document.PartUri); XElement document; using (Stream stream = documentPart.GetStream()) { document = XElement.Load(stream); } XElement updatedDocument = new XElement( document.Name, document.Attributes(), document.Nodes().Select(x => UpdateReferences(x, footnoteSequence))); updatedDocument.WriteTo(documentPart); return(new Footnotes(result)); }