WmlComparer.Private.Methods.Util.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright (c) Microsoft. All rights reserved.
  2. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.IO.Packaging;
  7. using System.Linq;
  8. using System.Xml.Linq;
  9. namespace OpenXmlPowerTools
  10. {
  11. public static partial class WmlComparer
  12. {
  13. private static XElement MoveRelatedPartsToDestination(
  14. PackagePart partOfDeletedContent,
  15. PackagePart partInNewDocument,
  16. XElement contentElement)
  17. {
  18. List<XElement> elementsToUpdate = contentElement
  19. .Descendants()
  20. .Where(d => d.Attributes().Any(a => ComparisonUnitWord.RelationshipAttributeNames.Contains(a.Name)))
  21. .ToList();
  22. foreach (XElement element in elementsToUpdate)
  23. {
  24. List<XAttribute> attributesToUpdate = element
  25. .Attributes()
  26. .Where(a => ComparisonUnitWord.RelationshipAttributeNames.Contains(a.Name))
  27. .ToList();
  28. foreach (XAttribute att in attributesToUpdate)
  29. {
  30. var rId = (string) att;
  31. PackageRelationship relationshipForDeletedPart = partOfDeletedContent.GetRelationship(rId);
  32. Uri targetUri = PackUriHelper
  33. .ResolvePartUri(
  34. new Uri(partOfDeletedContent.Uri.ToString(), UriKind.Relative),
  35. relationshipForDeletedPart.TargetUri);
  36. PackagePart relatedPackagePart = partOfDeletedContent.Package.GetPart(targetUri);
  37. string[] uriSplit = relatedPackagePart.Uri.ToString().Split('/');
  38. string[] last = uriSplit[uriSplit.Length - 1].Split('.');
  39. string uriString;
  40. if (last.Length == 2)
  41. {
  42. uriString = uriSplit.SkipLast(1).Select(p => p + "/").StringConcatenate() +
  43. "P" + Guid.NewGuid().ToString().Replace("-", "") + "." + last[1];
  44. }
  45. else
  46. {
  47. uriString = uriSplit.SkipLast(1).Select(p => p + "/").StringConcatenate() +
  48. "P" + Guid.NewGuid().ToString().Replace("-", "");
  49. }
  50. Uri uri = relatedPackagePart.Uri.IsAbsoluteUri
  51. ? new Uri(uriString, UriKind.Absolute)
  52. : new Uri(uriString, UriKind.Relative);
  53. PackagePart newPart = partInNewDocument.Package.CreatePart(uri, relatedPackagePart.ContentType);
  54. // ReSharper disable once PossibleNullReferenceException
  55. using (Stream oldPartStream = relatedPackagePart.GetStream())
  56. using (Stream newPartStream = newPart.GetStream())
  57. {
  58. FileUtils.CopyStream(oldPartStream, newPartStream);
  59. }
  60. string newRid = "R" + Guid.NewGuid().ToString().Replace("-", "");
  61. partInNewDocument.CreateRelationship(newPart.Uri, TargetMode.Internal,
  62. relationshipForDeletedPart.RelationshipType, newRid);
  63. att.Value = newRid;
  64. if (newPart.ContentType.EndsWith("xml"))
  65. {
  66. XDocument newPartXDoc;
  67. using (Stream stream = newPart.GetStream())
  68. {
  69. newPartXDoc = XDocument.Load(stream);
  70. MoveRelatedPartsToDestination(relatedPackagePart, newPart, newPartXDoc.Root);
  71. }
  72. using (Stream stream = newPart.GetStream())
  73. newPartXDoc.Save(stream);
  74. }
  75. }
  76. }
  77. return contentElement;
  78. }
  79. private static XAttribute GetXmlSpaceAttribute(string textOfTextElement)
  80. {
  81. if (char.IsWhiteSpace(textOfTextElement[0]) ||
  82. char.IsWhiteSpace(textOfTextElement[textOfTextElement.Length - 1]))
  83. return new XAttribute(XNamespace.Xml + "space", "preserve");
  84. return null;
  85. }
  86. }
  87. }