Skip to content

Commit 1e6ebc9

Browse files
authored
Only unload part when saving part if it is not the same element (#1828)
This is fall out from #1760 that removes the loaded part but doesn't check if we're saving an existing root element Fixes #1771
1 parent 1c165bd commit 1e6ebc9

File tree

5 files changed

+46
-18
lines changed

5 files changed

+46
-18
lines changed

Open-XML-SDK.sln

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ Global
217217
{890B74DD-6316-4D56-B42A-5D66F10F88C6} = {C5AE39F0-A152-471A-B90E-B8F4E94AA6C2}
218218
{5DE9FB8F-A7C2-4038-A4A8-1622CDB6821A} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
219219
{F48B7D50-16CB-4BEF-A614-2DED9960AF09} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
220-
{C91489AB-FF14-4FAD-BA51-35371ADD7E1C} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
221-
{BB5DF535-E849-42AC-852A-A6D4815347C0} = {3653266D-2C88-4487-8977-839CB3E78A0A}
222-
{5241BCF2-331D-428E-A9C4-F8DF92C8F726} = {A4DF60EB-3AA5-48F0-B4D2-3F94B8E62F03}
220+
{C91489AB-FF14-4FAD-BA51-35371ADD7E1C} = {3653266D-2C88-4487-8977-839CB3E78A0A}
221+
{BB5DF535-E849-42AC-852A-A6D4815347C0} = {A4DF60EB-3AA5-48F0-B4D2-3F94B8E62F03}
222+
{5241BCF2-331D-428E-A9C4-F8DF92C8F726} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
223223
{3ECC7570-3501-479D-9CD9-64799C2AD149} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
224224
{BADAC0CC-F3E6-440E-B322-DA2B97625F26} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}
225225
{8EE9F34E-EAA1-4F03-B388-8076CE44DD7B} = {7DAF7304-40CC-4180-88A5-9A89DD13C565}

src/DocumentFormat.OpenXml.Framework/Framework/Metadata/ElementFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace DocumentFormat.OpenXml.Framework.Metadata
88
{
9-
[DebuggerDisplay("{Namespace}:{Name}")]
9+
[DebuggerDisplay("{QName,nq}")]
1010
internal sealed class ElementFactory
1111
{
1212
private readonly Func<OpenXmlElement> _factory;

src/DocumentFormat.OpenXml.Framework/OpenXmlPartRootElement.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,10 @@ internal void SaveToPart(OpenXmlPart openXmlPart)
191191
throw new ArgumentNullException(nameof(openXmlPart));
192192
}
193193

194-
using (Stream partStream = openXmlPart.GetStream(FileMode.Create))
195-
{
196-
Save(partStream);
197-
}
194+
// If we're saving the existing root to the the part, we don't need to unload the root as they're already equal
195+
using var partStream = openXmlPart.GetStream(FileMode.Create, unloadRootOnChange: !ReferenceEquals(this, openXmlPart.PartRootElement));
196+
197+
Save(partStream);
198198
}
199199

200200
/// <summary>

src/DocumentFormat.OpenXml.Framework/Packaging/OpenXmlPart.cs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,10 @@ public IEnumerable<OpenXmlPart> GetParentParts()
236236
/// <param name="mode">The I/O mode to be used to open the content stream.</param>
237237
/// <returns>The content stream of the part. </returns>
238238
public Stream GetStream(FileMode mode)
239-
{
240-
return GetStream(mode, Features.GetRequired<IPackageFeature>().Package.FileOpenAccess);
241-
}
239+
=> GetStream(mode, unloadRootOnChange: true);
240+
241+
internal Stream GetStream(FileMode mode, bool unloadRootOnChange)
242+
=> GetStream(mode, Features.GetRequired<IPackageFeature>().Package.FileOpenAccess, unloadRootOnChange);
242243

243244
/// <summary>
244245
/// Returns the part content stream that was opened using a specified FileMode and FileAccess.
@@ -247,20 +248,26 @@ public Stream GetStream(FileMode mode)
247248
/// <param name="access">The access permissions to be used to open the content stream.</param>
248249
/// <returns>The content stream of the part. </returns>
249250
public Stream GetStream(FileMode mode, FileAccess access)
251+
=> GetStream(mode, access, true);
252+
253+
internal Stream GetStream(FileMode mode, FileAccess access, bool unloadRootOnChange)
250254
{
251255
ThrowIfObjectDisposed();
252256

253257
var stream = PackagePart.GetStream(mode, access);
254258

255-
if (mode is FileMode.Create || stream.Length == 0)
259+
if (unloadRootOnChange)
256260
{
257-
UnloadRootElement();
258-
return new UnloadingRootElementStream(this, stream);
259-
}
261+
if (mode is FileMode.Create || stream.Length == 0)
262+
{
263+
UnloadRootElement();
264+
return new UnloadingRootElementStream(this, stream);
265+
}
260266

261-
if (stream.CanWrite)
262-
{
263-
return new UnloadingRootElementStream(this, stream);
267+
if (stream.CanWrite)
268+
{
269+
return new UnloadingRootElementStream(this, stream);
270+
}
264271
}
265272

266273
return stream;

test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlPartTest.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,5 +321,26 @@ public void UnloadRootElementTest()
321321
}
322322
}
323323
}
324+
325+
[Fact]
326+
public void SavingPartDoesNotUnloadRoot()
327+
{
328+
// Arrange
329+
using Stream stream = new MemoryStream();
330+
using var testDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document);
331+
332+
var mainPart = testDocument.AddMainDocumentPart();
333+
mainPart.Document = new Document();
334+
mainPart.Document.AppendChild(new Body());
335+
336+
var rootElement = mainPart.RootElement;
337+
Assert.NotNull(rootElement);
338+
339+
// Act
340+
mainPart.RootElement.Save();
341+
342+
// Assert
343+
Assert.Same(rootElement, mainPart.RootElement);
344+
}
324345
}
325346
}

0 commit comments

Comments
 (0)