From caa11106fb1f3047d2c911d3436b4fd75b2f0a35 Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:47:19 -0700 Subject: [PATCH 1/8] add IsValidChild method --- .../OpenXmlCompositeElement.cs | 1 - .../OpenXmlElement.cs | 15 +++++++++++++++ .../PublicAPI/PublicAPI.Shipped.txt | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index 4d3ec8a5a..1011fc604 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -3,7 +3,6 @@ using DocumentFormat.OpenXml.Framework; using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs index 623ef993d..01ed34b48 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs @@ -1330,6 +1330,21 @@ public bool IsBefore(OpenXmlElement element) return GetOrder(this, element) == ElementOrder.Before; } + /// + /// Determines if the specified element is a valid child of the current element. + /// + /// The element to check. + /// True if the specified element is a valid child; otherwise, false. + public bool IsValidChild(OpenXmlElement element) + { + if (element is null) + { + throw new ArgumentNullException(nameof(element)); + } + + return Metadata.Children.Elements.Any(el => el.Type.Name.Equals(element.Metadata.Type.Name)); + } + private enum ElementOrder { Same, // same element diff --git a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt index c7d7da820..19bdad638 100644 --- a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt +++ b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt @@ -1009,3 +1009,4 @@ DocumentFormat.OpenXml.OpenXmlPartWriterSettings.Encoding.set -> void DocumentFormat.OpenXml.OpenXmlPartWriterSettings.OpenXmlPartWriterSettings() -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(DocumentFormat.OpenXml.Packaging.OpenXmlPart! openXmlPart, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(System.IO.Stream! partStream, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void +DocumentFormat.OpenXml.OpenXmlElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool From 738b2f2ab0571d94a9f8890ad222456e07382b45 Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:53:10 -0700 Subject: [PATCH 2/8] don't edit openxmlcompositelement --- src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index 1011fc604..4d3ec8a5a 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -3,6 +3,7 @@ using DocumentFormat.OpenXml.Framework; using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; From c53a74ad6c9b63b1c8a43977b6aeae4ffc227c9d Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Fri, 4 Apr 2025 16:19:32 -0700 Subject: [PATCH 3/8] add tests --- .../ofapiTest/OpenXmlElementTest2.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs index eae9ffe8f..26fd797fb 100644 --- a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs +++ b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs @@ -240,5 +240,43 @@ public void GetOrAddFirstChildTest() var r2 = p.GetOrAddFirstChild(); Assert.Same(r, r2); } + + [Fact] + public void IsValidChild_ValidChild_ReturnsTrue() + { + // Arrange + var parentElement = new Paragraph(); + var validChild = new Run(); + + // Act + var result = parentElement.IsValidChild(validChild); + + // Assert + Assert.True(result); + } + + [Fact] + public void IsValidChild_InvalidChild_ReturnsFalse() + { + // Arrange + var parentElement = new Paragraph(); + var invalidChild = new Table(); + + // Act + var result = parentElement.IsValidChild(invalidChild); + + // Assert + Assert.False(result); + } + + [Fact] + public void IsValidChild_NullChild_ThrowsArgumentNullException() + { + // Arrange + var parentElement = new Paragraph(); + + // Act & Assert + Assert.Throws(() => parentElement.IsValidChild(null)); + } } } From ecacca650c4202cefa80984888f054c58ffc03cb Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Fri, 25 Apr 2025 10:56:35 -0700 Subject: [PATCH 4/8] make IsValidChild virtual in OpenXmlElement and overridden in OpenXmlCompositeElement, return false instead of throw when element child to test is null --- .../OpenXmlCompositeElement.cs | 16 +++++++++++++ .../OpenXmlElement.cs | 9 ++------ .../PublicAPI/PublicAPI.Shipped.txt | 3 ++- .../ofapiTest/OpenXmlElementTest2.cs | 23 +++++++++++-------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index 4d3ec8a5a..ffb988ad8 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -9,6 +9,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Xml; @@ -534,6 +535,21 @@ public override void RemoveAllChildren() #endregion + /// + /// Determines if the specified element is a valid child of the current element. + /// + /// The element to check. + /// True if the specified element is a valid child; otherwise, false. + public override bool IsValidChild(OpenXmlElement element) + { + if (element is null) + { + return false; + } + + return Metadata.Children.Elements.Any(el => el.Type.Name.Equals(element.Metadata.Type.Name)); + } + /// /// Saves all of the current node's children to the specified XmlWriter. /// diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs index 01ed34b48..30e537880 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs @@ -1335,14 +1335,9 @@ public bool IsBefore(OpenXmlElement element) /// /// The element to check. /// True if the specified element is a valid child; otherwise, false. - public bool IsValidChild(OpenXmlElement element) + public virtual bool IsValidChild(OpenXmlElement element) { - if (element is null) - { - throw new ArgumentNullException(nameof(element)); - } - - return Metadata.Children.Elements.Any(el => el.Type.Name.Equals(element.Metadata.Type.Name)); + return false; } private enum ElementOrder diff --git a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt index 19bdad638..8f317d788 100644 --- a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt +++ b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt @@ -1009,4 +1009,5 @@ DocumentFormat.OpenXml.OpenXmlPartWriterSettings.Encoding.set -> void DocumentFormat.OpenXml.OpenXmlPartWriterSettings.OpenXmlPartWriterSettings() -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(DocumentFormat.OpenXml.Packaging.OpenXmlPart! openXmlPart, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(System.IO.Stream! partStream, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void -DocumentFormat.OpenXml.OpenXmlElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool +virtual DocumentFormat.OpenXml.OpenXmlElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool +override DocumentFormat.OpenXml.OpenXmlCompositeElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool diff --git a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs index 26fd797fb..a9514f910 100644 --- a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs +++ b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs @@ -245,11 +245,11 @@ public void GetOrAddFirstChildTest() public void IsValidChild_ValidChild_ReturnsTrue() { // Arrange - var parentElement = new Paragraph(); - var validChild = new Run(); + Paragraph parentElement = new(); + Run validChild = new(); // Act - var result = parentElement.IsValidChild(validChild); + bool result = parentElement.IsValidChild(validChild); // Assert Assert.True(result); @@ -259,24 +259,27 @@ public void IsValidChild_ValidChild_ReturnsTrue() public void IsValidChild_InvalidChild_ReturnsFalse() { // Arrange - var parentElement = new Paragraph(); - var invalidChild = new Table(); + Paragraph parentElement = new(); + Table invalidChild = new(); // Act - var result = parentElement.IsValidChild(invalidChild); + bool result = parentElement.IsValidChild(invalidChild); // Assert Assert.False(result); } [Fact] - public void IsValidChild_NullChild_ThrowsArgumentNullException() + public void IsValidChild_NullChild_ReturnsFalse() { // Arrange - var parentElement = new Paragraph(); + Paragraph parentElement = new(); - // Act & Assert - Assert.Throws(() => parentElement.IsValidChild(null)); + // Act + bool result = parentElement.IsValidChild(null); + + // Assert + Assert.False(result); } } } From 4d37e799dcc52574b89c773c04dda8ea8c0adb4c Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Mon, 28 Apr 2025 13:49:45 -0700 Subject: [PATCH 5/8] remove duplicate test --- .../ofapiTest/OpenXmlElementTest2.cs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs index 18c4d722c..5eb785b1c 100644 --- a/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs +++ b/test/DocumentFormat.OpenXml.Tests/ofapiTest/OpenXmlElementTest2.cs @@ -8,7 +8,6 @@ using DocumentFormat.OpenXml.Wordprocessing; using System; using System.IO; -using System.Xml; using Xunit; namespace DocumentFormat.OpenXml.Tests @@ -198,21 +197,6 @@ public void CanSetNullValue() Assert.Null(cell.Child); } - /// - /// A test for OpenXmlElement.GetOrAddFirstChild. - /// - [Fact] - public void GetOrAddFirstChildTest() - { - Paragraph p = new(); - Run r = p.GetOrAddFirstChild(); - Assert.NotNull(r); - Assert.Same(r, p.GetFirstChild()); - - var r2 = p.GetOrAddFirstChild(); - Assert.Same(r, r2); - } - private class WithChildElement : OpenXmlCompositeElement { public ChildElement Child From e688eedb64950cf548732fe91f8a6c8383d4c249 Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Mon, 12 May 2025 10:53:44 -0700 Subject: [PATCH 6/8] use foreach instead of linq --- .../OpenXmlCompositeElement.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index ffb988ad8..6ff9ffddc 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -547,7 +547,15 @@ public override bool IsValidChild(OpenXmlElement element) return false; } - return Metadata.Children.Elements.Any(el => el.Type.Name.Equals(element.Metadata.Type.Name)); + foreach (var elem in Metadata.Children.Elements) + { + if (elem.Type.Name.Equals(element.Metadata.Type.Name)) + { + return true; + } + } + + return false; } /// From c08a012f4f6eb0cb1da1e813f69889404580e87f Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Mon, 12 May 2025 11:59:33 -0700 Subject: [PATCH 7/8] remove unused usings --- src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index 6ff9ffddc..eb07212ed 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -3,13 +3,11 @@ using DocumentFormat.OpenXml.Framework; using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; -using System.Linq; using System.Text; using System.Xml; From 01a504f33a7db78e0a2ff7da9d419717db887be5 Mon Sep 17 00:00:00 2001 From: Michael Bowen <10384982+mikeebowen@users.noreply.github.com> Date: Wed, 14 May 2025 11:51:51 -0700 Subject: [PATCH 8/8] make OpenXmlCompositeElement.IsValidChild virtual --- .../OpenXmlCompositeElement.cs | 11 +++++++---- .../OpenXmlElement.cs | 10 ---------- .../PublicAPI/PublicAPI.Shipped.txt | 3 +-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs index eb07212ed..9a7312433 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlCompositeElement.cs @@ -534,11 +534,14 @@ public override void RemoveAllChildren() #endregion /// - /// Determines if the specified element is a valid child of the current element. + /// Determines whether the specified is a valid child element + /// for this according to the schema definition. /// - /// The element to check. - /// True if the specified element is a valid child; otherwise, false. - public override bool IsValidChild(OpenXmlElement element) + /// The to validate as a child. + /// + /// true if the specified element is a valid child; otherwise, false. + /// + public virtual bool IsValidChild(OpenXmlElement element) { if (element is null) { diff --git a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs index 56ca2c4c7..59a63d6f7 100644 --- a/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs +++ b/src/DocumentFormat.OpenXml.Framework/OpenXmlElement.cs @@ -1330,16 +1330,6 @@ public bool IsBefore(OpenXmlElement element) return GetOrder(this, element) == ElementOrder.Before; } - /// - /// Determines if the specified element is a valid child of the current element. - /// - /// The element to check. - /// True if the specified element is a valid child; otherwise, false. - public virtual bool IsValidChild(OpenXmlElement element) - { - return false; - } - private enum ElementOrder { Same, // same element diff --git a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt index 8f317d788..abbee3a8e 100644 --- a/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt +++ b/src/DocumentFormat.OpenXml.Framework/PublicAPI/PublicAPI.Shipped.txt @@ -1009,5 +1009,4 @@ DocumentFormat.OpenXml.OpenXmlPartWriterSettings.Encoding.set -> void DocumentFormat.OpenXml.OpenXmlPartWriterSettings.OpenXmlPartWriterSettings() -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(DocumentFormat.OpenXml.Packaging.OpenXmlPart! openXmlPart, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void DocumentFormat.OpenXml.OpenXmlPartWriter.OpenXmlPartWriter(System.IO.Stream! partStream, DocumentFormat.OpenXml.OpenXmlPartWriterSettings! settings) -> void -virtual DocumentFormat.OpenXml.OpenXmlElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool -override DocumentFormat.OpenXml.OpenXmlCompositeElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool +virtual DocumentFormat.OpenXml.OpenXmlCompositeElement.IsValidChild(DocumentFormat.OpenXml.OpenXmlElement! element) -> bool