Skip to content

Commit f990ae8

Browse files
authored
Add GetOrAddFirstChild method (#1904)
- #1548
1 parent 7452a11 commit f990ae8

File tree

3 files changed

+36
-1
lines changed

3 files changed

+36
-1
lines changed

src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,11 +796,30 @@ public void RemoveNamespaceDeclaration(string prefix)
796796
/// Finds the first child element in type T.
797797
/// </summary>
798798
/// <typeparam name="T">Type of element.</typeparam>
799-
/// <returns></returns>
799+
/// <returns>The first child element of type T or null</returns>
800800
public T? GetFirstChild<T>()
801801
where T : OpenXmlElement
802802
=> ChildElements.First<T>();
803803

804+
/// <summary>
805+
/// Finds the first child element of <typeparam ref="T"/> or adds a new element if it does not exist.
806+
/// </summary>
807+
/// <typeparam name="T">Type of element.</typeparam>
808+
/// <returns>The new or existing OpenXmlElement</returns>
809+
public T GetOrAddFirstChild<T>()
810+
where T : OpenXmlElement, new()
811+
{
812+
var child = GetFirstChild<T>();
813+
814+
if (child is null)
815+
{
816+
child = new T();
817+
AppendChild(child);
818+
}
819+
820+
return child;
821+
}
822+
804823
/// <summary>
805824
/// Gets the OpenXmlElement element that immediately precedes the current OpenXmlElement element.
806825
/// Returns null (Nothing in Visual Basic ) if there is no preceding OpenXmlElement element.

src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ DocumentFormat.OpenXml.OpenXmlElement.Features.get -> DocumentFormat.OpenXml.Fea
270270
DocumentFormat.OpenXml.OpenXmlElement.GetAttribute(string! localName, string! namespaceUri) -> DocumentFormat.OpenXml.OpenXmlAttribute
271271
DocumentFormat.OpenXml.OpenXmlElement.GetAttributes() -> System.Collections.Generic.IList<DocumentFormat.OpenXml.OpenXmlAttribute>!
272272
DocumentFormat.OpenXml.OpenXmlElement.GetFirstChild<T>() -> T?
273+
DocumentFormat.OpenXml.OpenXmlElement.GetOrAddFirstChild<T>() -> T!
273274
DocumentFormat.OpenXml.OpenXmlElement.HasAttributes.get -> bool
274275
DocumentFormat.OpenXml.OpenXmlElement.InsertAfterSelf<T>(T! newElement) -> T!
275276
DocumentFormat.OpenXml.OpenXmlElement.InsertBeforeSelf<T>(T! newElement) -> T!

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,5 +216,20 @@ internal override void ConfigureMetadata(ElementMetadata.Builder builder)
216216
private class ChildElement : OpenXmlLeafElement
217217
{
218218
}
219+
220+
/// <summary>
221+
/// A test for OpenXmlElement.GetOrAddFirstChild.
222+
/// </summary>
223+
[Fact]
224+
public void GetOrAddFirstChildTest()
225+
{
226+
Paragraph p = new();
227+
Run r = p.GetOrAddFirstChild<Run>();
228+
Assert.NotNull(r);
229+
Assert.Same(r, p.GetFirstChild<Run>());
230+
231+
var r2 = p.GetOrAddFirstChild<Run>();
232+
Assert.Same(r, r2);
233+
}
219234
}
220235
}

0 commit comments

Comments
 (0)