diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/AbstractUpgradeStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/AbstractUpgradeStrategy.java index 7da111eeb197..becc28b0b554 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/AbstractUpgradeStrategy.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/AbstractUpgradeStrategy.java @@ -129,7 +129,7 @@ public static Coordinates extractArtifactCoordinatesWithParentResolution( // If groupId or version is missing, try to get from parent if (groupId == null || version == null) { - Element parentElement = root.child(PARENT).orElse(null); + Element parentElement = root.childElement(PARENT).orElse(null); if (parentElement != null) { if (groupId == null) { groupId = parentElement.childTextTrimmed(MavenPomElements.Elements.GROUP_ID); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java index af9064c11c7e..96bae531527c 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategy.java @@ -205,22 +205,25 @@ private boolean fixDuplicateDependencies(Document pomDocument, UpgradeContext co Stream dependencyContainers = Stream.concat( // Root level dependencies Stream.of( - new DependencyContainer(root.child(DEPENDENCIES).orElse(null), DEPENDENCIES), new DependencyContainer( - root.child(DEPENDENCY_MANAGEMENT) - .flatMap(dm -> dm.child(DEPENDENCIES)) + root.childElement(DEPENDENCIES).orElse(null), DEPENDENCIES), + new DependencyContainer( + root.childElement(DEPENDENCY_MANAGEMENT) + .flatMap(dm -> dm.childElement(DEPENDENCIES)) .orElse(null), DEPENDENCY_MANAGEMENT)) .filter(container -> container.element != null), // Profile dependencies - root.child(PROFILES).stream() - .flatMap(profiles -> profiles.children(PROFILE)) + root.childElement(PROFILES).stream() + .flatMap(profiles -> profiles.childElements(PROFILE)) .flatMap(profile -> Stream.of( new DependencyContainer( - profile.child(DEPENDENCIES).orElse(null), "profile dependencies"), + profile.childElement(DEPENDENCIES) + .orElse(null), + "profile dependencies"), new DependencyContainer( - profile.child(DEPENDENCY_MANAGEMENT) - .flatMap(dm -> dm.child(DEPENDENCIES)) + profile.childElement(DEPENDENCY_MANAGEMENT) + .flatMap(dm -> dm.childElement(DEPENDENCIES)) .orElse(null), "profile dependencyManagement")) .filter(container -> container.element != null))); @@ -249,12 +252,13 @@ private boolean fixDuplicatePlugins(Document pomDocument, UpgradeContext context // Collect all build elements to process Stream buildContainers = Stream.concat( // Root level build - Stream.of(new BuildContainer(root.child(BUILD).orElse(null), BUILD)) + Stream.of(new BuildContainer(root.childElement(BUILD).orElse(null), BUILD)) .filter(container -> container.element != null), // Profile builds - root.child(PROFILES).stream() - .flatMap(profiles -> profiles.children(PROFILE)) - .map(profile -> new BuildContainer(profile.child(BUILD).orElse(null), "profile build")) + root.childElement(PROFILES).stream() + .flatMap(profiles -> profiles.childElements(PROFILE)) + .map(profile -> + new BuildContainer(profile.childElement(BUILD).orElse(null), "profile build")) .filter(container -> container.element != null)); return buildContainers @@ -282,15 +286,16 @@ private boolean fixUnsupportedRepositoryExpressions(Document pomDocument, Upgrad Stream repositoryContainers = Stream.concat( // Root level repositories Stream.of( - root.child(REPOSITORIES).orElse(null), - root.child(PLUGIN_REPOSITORIES).orElse(null)) + root.childElement(REPOSITORIES).orElse(null), + root.childElement(PLUGIN_REPOSITORIES).orElse(null)) .filter(Objects::nonNull), // Profile repositories - root.child(PROFILES).stream() - .flatMap(profiles -> profiles.children(PROFILE)) + root.childElement(PROFILES).stream() + .flatMap(profiles -> profiles.childElements(PROFILE)) .flatMap(profile -> Stream.of( - profile.child(REPOSITORIES).orElse(null), - profile.child(PLUGIN_REPOSITORIES).orElse(null)) + profile.childElement(REPOSITORIES).orElse(null), + profile.childElement(PLUGIN_REPOSITORIES) + .orElse(null)) .filter(Objects::nonNull))); return repositoryContainers @@ -305,12 +310,12 @@ private boolean fixIncorrectParentRelativePaths( Document pomDocument, Path pomPath, Map pomMap, UpgradeContext context) { Element root = pomDocument.root(); - Element parentElement = root.child(PARENT).orElse(null); + Element parentElement = root.childElement(PARENT).orElse(null); if (parentElement == null) { return false; // No parent to fix } - Element relativePathElement = parentElement.child(RELATIVE_PATH).orElse(null); + Element relativePathElement = parentElement.childElement(RELATIVE_PATH).orElse(null); String currentRelativePath = relativePathElement != null ? relativePathElement.textContent().trim() : DEFAULT_PARENT_RELATIVE_PATH; @@ -351,7 +356,8 @@ private Stream findElementsWithAttribute(Element element, String attrib return attr != null && attributeValue.equals(attr); }), // Recursively check children - element.children().flatMap(child -> findElementsWithAttribute(child, attributeName, attributeValue))); + element.childElements() + .flatMap(child -> findElementsWithAttribute(child, attributeName, attributeValue))); } /** @@ -359,7 +365,8 @@ private Stream findElementsWithAttribute(Element element, String attrib */ private boolean fixDuplicateDependenciesInSection( Element dependenciesElement, UpgradeContext context, String sectionName) { - List dependencies = dependenciesElement.children(DEPENDENCY).toList(); + List dependencies = + dependenciesElement.childElements(DEPENDENCY).toList(); Map seenDependencies = new HashMap<>(); List duplicates = dependencies.stream() @@ -394,15 +401,16 @@ private String createDependencyKey(Element dependency) { private boolean fixPluginsInBuildElement(Element buildElement, UpgradeContext context, String sectionName) { boolean fixed = false; - Element pluginsElement = buildElement.child(PLUGINS).orElse(null); + Element pluginsElement = buildElement.childElement(PLUGINS).orElse(null); if (pluginsElement != null) { fixed |= fixDuplicatePluginsInSection(pluginsElement, context, sectionName + "/" + PLUGINS); } - Element pluginManagementElement = buildElement.child(PLUGIN_MANAGEMENT).orElse(null); + Element pluginManagementElement = + buildElement.childElement(PLUGIN_MANAGEMENT).orElse(null); if (pluginManagementElement != null) { Element managedPluginsElement = - pluginManagementElement.child(PLUGINS).orElse(null); + pluginManagementElement.childElement(PLUGINS).orElse(null); if (managedPluginsElement != null) { fixed |= fixDuplicatePluginsInSection( managedPluginsElement, context, sectionName + "/" + PLUGIN_MANAGEMENT + "/" + PLUGINS); @@ -416,7 +424,7 @@ private boolean fixPluginsInBuildElement(Element buildElement, UpgradeContext co * Fixes duplicate plugins within a specific plugins section. */ private boolean fixDuplicatePluginsInSection(Element pluginsElement, UpgradeContext context, String sectionName) { - List plugins = pluginsElement.children(PLUGIN).toList(); + List plugins = pluginsElement.childElements(PLUGIN).toList(); Map seenPlugins = new HashMap<>(); List duplicates = plugins.stream() @@ -460,10 +468,11 @@ private boolean fixRepositoryExpressions( boolean fixed = false; String elementType = repositoriesElement.name().equals(REPOSITORIES) ? REPOSITORY : PLUGIN_REPOSITORY; - List repositories = repositoriesElement.children(elementType).toList(); + List repositories = + repositoriesElement.childElements(elementType).toList(); for (Element repository : repositories) { - Element urlElement = repository.child("url").orElse(null); + Element urlElement = repository.childElement("url").orElse(null); if (urlElement != null) { String url = urlElement.textContent().trim(); if (url.contains("${")) { diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.java index 2f987199c148..5c27eb2774cf 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtils.java @@ -45,18 +45,18 @@ *

Many operations can be performed directly using DomTrip's Element API: *

{@code
  * // Find child element
- * Element child = parent.child("version").orElse(null);
+ * Element child = parent.childElement("version").orElse(null);
  *
  * // Check if child exists
- * boolean hasVersion = parent.child("version").isPresent();
+ * boolean hasVersion = parent.childElement("version").isPresent();
  *
  * // Get child text content
- * String version = parent.child("version")
+ * String version = parent.childElement("version")
  *     .map(Element::textContent)
  *     .orElse(null);
  *
  * // Get trimmed text content
- * String trimmedVersion = parent.child("version")
+ * String trimmedVersion = parent.childElement("version")
  *     .map(Element::textContentTrimmed)
  *     .orElse(null);
  *
@@ -119,7 +119,7 @@ public static Element insertContentElement(Element parent, String name, String c
      *
      */
     public static Element findChildElement(Element parent, String name) {
-        return parent.child(name).orElse(null);
+        return parent.childElement(name).orElse(null);
     }
 
     /**
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategy.java
index 800136cfddcb..2ce0d3fa02f0 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategy.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategy.java
@@ -167,7 +167,7 @@ private boolean applyLimitedParentInference(UpgradeContext context, Document pom
         Element root = pomDocument.root();
 
         // Check if this POM has a parent
-        Element parentElement = root.child(PARENT).orElse(null);
+        Element parentElement = root.childElement(PARENT).orElse(null);
         if (parentElement == null) {
             return false;
         }
@@ -184,7 +184,7 @@ private boolean applyFullParentInference(UpgradeContext context, Map profiles.children(PROFILE))
-                .map(profile -> profile.child(DEPENDENCY_MANAGEMENT)
-                        .flatMap(dm -> dm.child(DEPENDENCIES))
+        boolean profileChanges = root.childElement(PROFILES).stream()
+                .flatMap(profiles -> profiles.childElements(PROFILE))
+                .map(profile -> profile.childElement(DEPENDENCY_MANAGEMENT)
+                        .flatMap(dm -> dm.childElement(DEPENDENCIES))
                         .map(deps -> removeManagedDependenciesFromSection(
                                 context, deps, allGAVs, "profile dependencyManagement"))
                         .orElse(false))
@@ -236,15 +237,15 @@ private boolean applyDependencyInferenceRedundancy(
         boolean hasChanges = false;
 
         // Process main dependencies
-        Element dependenciesElement = root.child(DEPENDENCIES).orElse(null);
+        Element dependenciesElement = root.childElement(DEPENDENCIES).orElse(null);
         if (dependenciesElement != null) {
             hasChanges |= removeDependencyInferenceFromSection(context, dependenciesElement, pomMap, DEPENDENCIES);
         }
 
         // Process profile dependencies
-        boolean profileDependencyChanges = root.child(PROFILES).stream()
-                .flatMap(profiles -> profiles.children(PROFILE))
-                .map(profile -> profile.child(DEPENDENCIES)
+        boolean profileDependencyChanges = root.childElement(PROFILES).stream()
+                .flatMap(profiles -> profiles.childElements(PROFILE))
+                .map(profile -> profile.childElement(DEPENDENCIES)
                         .map(deps ->
                                 removeDependencyInferenceFromSection(context, deps, pomMap, "profile dependencies"))
                         .orElse(false))
@@ -253,12 +254,14 @@ private boolean applyDependencyInferenceRedundancy(
         hasChanges |= profileDependencyChanges;
 
         // Process build plugin dependencies
-        boolean pluginDependencyChanges = root.child(BUILD).flatMap(build -> build.child(PLUGINS)).stream()
-                .flatMap(plugins -> plugins.children(PLUGIN))
-                .map(plugin -> plugin.child(DEPENDENCIES)
-                        .map(deps -> removeDependencyInferenceFromSection(context, deps, pomMap, "plugin dependencies"))
-                        .orElse(false))
-                .reduce(false, Boolean::logicalOr);
+        boolean pluginDependencyChanges =
+                root.childElement(BUILD).flatMap(build -> build.childElement(PLUGINS)).stream()
+                        .flatMap(plugins -> plugins.childElements(PLUGIN))
+                        .map(plugin -> plugin.childElement(DEPENDENCIES)
+                                .map(deps -> removeDependencyInferenceFromSection(
+                                        context, deps, pomMap, "plugin dependencies"))
+                                .orElse(false))
+                        .reduce(false, Boolean::logicalOr);
 
         hasChanges |= pluginDependencyChanges;
 
@@ -274,7 +277,7 @@ private boolean applySubprojectsInference(UpgradeContext context, Document pomDo
         Element root = pomDocument.root();
 
         // Check main subprojects
-        Element subprojectsElement = root.child(SUBPROJECTS).orElse(null);
+        Element subprojectsElement = root.childElement(SUBPROJECTS).orElse(null);
         if (subprojectsElement != null) {
             if (isSubprojectsListRedundant(subprojectsElement, pomPath)) {
                 DomUtils.removeElement(subprojectsElement);
@@ -284,9 +287,9 @@ private boolean applySubprojectsInference(UpgradeContext context, Document pomDo
         }
 
         // Check profiles for subprojects
-        boolean profileSubprojectsChanges = root.child(PROFILES).stream()
-                .flatMap(profiles -> profiles.children(PROFILE))
-                .map(profile -> profile.child(SUBPROJECTS)
+        boolean profileSubprojectsChanges = root.childElement(PROFILES).stream()
+                .flatMap(profiles -> profiles.childElements(PROFILE))
+                .map(profile -> profile.childElement(SUBPROJECTS)
                         .filter(subprojects -> isSubprojectsListRedundant(subprojects, pomPath))
                         .map(subprojects -> {
                             DomUtils.removeElement(subprojects);
@@ -338,7 +341,7 @@ private boolean trimParentElementLimited(UpgradeContext context, Element root, E
 
         // Remove child groupId if it matches parent groupId
         if (childGroupId != null && Objects.equals(childGroupId, parentGroupId)) {
-            Element childGroupIdElement = root.child(GROUP_ID).orElse(null);
+            Element childGroupIdElement = root.childElement(GROUP_ID).orElse(null);
             if (childGroupIdElement != null) {
                 DomUtils.removeElement(childGroupIdElement);
                 context.detail("Removed: child groupId (matches parent)");
@@ -348,7 +351,7 @@ private boolean trimParentElementLimited(UpgradeContext context, Element root, E
 
         // Remove child version if it matches parent version
         if (childVersion != null && Objects.equals(childVersion, parentVersion)) {
-            Element childVersionElement = root.child("version").orElse(null);
+            Element childVersionElement = root.childElement("version").orElse(null);
             if (childVersionElement != null) {
                 DomUtils.removeElement(childVersionElement);
                 context.detail("Removed: child version (matches parent)");
@@ -378,7 +381,8 @@ private boolean trimParentElementFull(
         if (isParentInReactor(parentElement, pomMap, context)) {
             // Remove parent groupId if child has no explicit groupId
             if (childGroupId == null) {
-                Element parentGroupIdElement = parentElement.child(GROUP_ID).orElse(null);
+                Element parentGroupIdElement =
+                        parentElement.childElement(GROUP_ID).orElse(null);
                 if (parentGroupIdElement != null) {
                     DomUtils.removeElement(parentGroupIdElement);
                     context.detail("Removed: parent groupId (child has no explicit groupId)");
@@ -388,7 +392,8 @@ private boolean trimParentElementFull(
 
             // Remove parent version if child has no explicit version
             if (childVersion == null) {
-                Element parentVersionElement = parentElement.child(VERSION).orElse(null);
+                Element parentVersionElement =
+                        parentElement.childElement(VERSION).orElse(null);
                 if (parentVersionElement != null) {
                     DomUtils.removeElement(parentVersionElement);
                     context.detail("Removed: parent version (child has no explicit version)");
@@ -399,7 +404,7 @@ private boolean trimParentElementFull(
             // Remove parent artifactId if it can be inferred from relativePath
             if (canInferParentArtifactId(parentElement, pomMap)) {
                 Element parentArtifactIdElement =
-                        parentElement.child(ARTIFACT_ID).orElse(null);
+                        parentElement.childElement(ARTIFACT_ID).orElse(null);
                 if (parentArtifactIdElement != null) {
                     DomUtils.removeElement(parentArtifactIdElement);
                     context.detail("Removed: parent artifactId (can be inferred from relativePath)");
@@ -438,7 +443,7 @@ private boolean isParentInReactor(Element parentElement, Map pom
         for (Document pomDocument : pomMap.values()) {
             Coordinates pomGAV =
                     AbstractUpgradeStrategy.extractArtifactCoordinatesWithParentResolution(context, pomDocument);
-            if (pomGAV != null && pomGAV.equals(parentGAV)) {
+            if (pomGAV != null && pomGAV.toGAV().equals(parentGAV.toGAV())) {
                 return true;
             }
         }
@@ -467,7 +472,7 @@ private boolean canInferParentArtifactId(Element parentElement, Map subprojectElements =
-                subprojectsElement.children(SUBPROJECT).toList();
+                subprojectsElement.childElements(SUBPROJECT).toList();
         if (subprojectElements.isEmpty()) {
             return true; // Empty list is redundant
         }
@@ -509,7 +514,8 @@ private boolean isSubprojectsListRedundant(Element subprojectsElement, Path pomP
      */
     private boolean removeManagedDependenciesFromSection(
             UpgradeContext context, Element dependencies, Set allGAVs, String sectionName) {
-        List dependencyElements = dependencies.children(DEPENDENCY).toList();
+        List dependencyElements =
+                dependencies.childElements(DEPENDENCY).toList();
 
         List projectArtifacts = dependencyElements.stream()
                 .filter(dependency -> {
@@ -542,7 +548,8 @@ private boolean removeManagedDependenciesFromSection(
      */
     private boolean removeDependencyInferenceFromSection(
             UpgradeContext context, Element dependencies, Map pomMap, String sectionName) {
-        List dependencyElements = dependencies.children(DEPENDENCY).toList();
+        List dependencyElements =
+                dependencies.childElements(DEPENDENCY).toList();
         boolean hasChanges = false;
 
         for (Element dependency : dependencyElements) {
@@ -556,7 +563,8 @@ private boolean removeDependencyInferenceFromSection(
                 if (dependencyPom != null) {
                     // Check if we can infer groupId
                     if (groupId != null && canInferDependencyGroupId(context, dependencyPom, groupId)) {
-                        Element groupIdElement = dependency.child(GROUP_ID).orElse(null);
+                        Element groupIdElement =
+                                dependency.childElement(GROUP_ID).orElse(null);
                         if (groupIdElement != null) {
                             DomUtils.removeElement(groupIdElement);
                             context.detail("Removed: " + "dependency groupId " + groupId + " from " + sectionName
@@ -567,7 +575,8 @@ private boolean removeDependencyInferenceFromSection(
 
                     // Check if we can infer version
                     if (version != null && canInferDependencyVersion(context, dependencyPom, version)) {
-                        Element versionElement = dependency.child(VERSION).orElse(null);
+                        Element versionElement =
+                                dependency.childElement(VERSION).orElse(null);
                         if (versionElement != null) {
                             DomUtils.removeElement(versionElement);
                             context.detail("Removed: " + "dependency version " + version + " from " + sectionName
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategy.java
index f0a5559d52a6..1cd965d9e98c 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategy.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategy.java
@@ -148,7 +148,7 @@ private Document performModelUpgrade(
 
         // Update model version element
         Element root = editor.root();
-        Element modelVersionElement = root.child(MODEL_VERSION).orElse(null);
+        Element modelVersionElement = root.childElement(MODEL_VERSION).orElse(null);
         if (modelVersionElement != null) {
             editor.setTextContent(modelVersionElement, targetModelVersion);
             context.detail("Updated modelVersion to " + targetModelVersion);
@@ -207,7 +207,7 @@ private void convertModulesToSubprojects(Editor editor, UpgradeContext context)
         }
 
         // Convert modules element to subprojects
-        Element modulesElement = root.child(MODULES).orElse(null);
+        Element modulesElement = root.childElement(MODULES).orElse(null);
         if (modulesElement != null) {
             // domtrip makes this much simpler - just change the element name
             // The formatting and structure are preserved automatically
@@ -215,7 +215,7 @@ private void convertModulesToSubprojects(Editor editor, UpgradeContext context)
             context.detail("Converted  to ");
 
             // Convert all module children to subproject
-            var moduleElements = modulesElement.children(MODULE).toList();
+            var moduleElements = modulesElement.childElements(MODULE).toList();
             for (Element moduleElement : moduleElements) {
                 moduleElement.name(SUBPROJECT);
             }
@@ -226,16 +226,17 @@ private void convertModulesToSubprojects(Editor editor, UpgradeContext context)
         }
 
         // Also check inside profiles
-        Element profilesElement = root.child(PROFILES).orElse(null);
+        Element profilesElement = root.childElement(PROFILES).orElse(null);
         if (profilesElement != null) {
-            var profileElements = profilesElement.children(PROFILE).toList();
+            var profileElements = profilesElement.childElements(PROFILE).toList();
             for (Element profileElement : profileElements) {
-                Element profileModulesElement = profileElement.child(MODULES).orElse(null);
+                Element profileModulesElement =
+                        profileElement.childElement(MODULES).orElse(null);
                 if (profileModulesElement != null) {
                     profileModulesElement.name(SUBPROJECTS);
 
                     var profileModuleElements =
-                            profileModulesElement.children(MODULE).toList();
+                            profileModulesElement.childElements(MODULE).toList();
                     for (Element moduleElement : profileModuleElements) {
                         moduleElement.name(SUBPROJECT);
                     }
@@ -293,17 +294,17 @@ private void upgradeDeprecatedPhases(Editor editor, UpgradeContext context) {
         int totalUpgrades = 0;
 
         // Upgrade phases in main build section
-        Element buildElement = root.child(BUILD).orElse(null);
+        Element buildElement = root.childElement(BUILD).orElse(null);
         if (buildElement != null) {
             totalUpgrades += upgradePhaseElements(buildElement, phaseUpgrades, context);
         }
 
         // Upgrade phases in profiles
-        Element profilesElement = root.child(PROFILES).orElse(null);
+        Element profilesElement = root.childElement(PROFILES).orElse(null);
         if (profilesElement != null) {
-            var profileElements = profilesElement.children(PROFILE).toList();
+            var profileElements = profilesElement.childElements(PROFILE).toList();
             for (Element profileElement : profileElements) {
-                Element profileBuildElement = profileElement.child(BUILD).orElse(null);
+                Element profileBuildElement = profileElement.childElement(BUILD).orElse(null);
                 if (profileBuildElement != null) {
                     totalUpgrades += upgradePhaseElements(profileBuildElement, phaseUpgrades, context);
                 }
@@ -348,16 +349,17 @@ private int upgradePhaseElements(Element buildElement, Map phase
         int upgrades = 0;
 
         // Check plugins section
-        Element pluginsElement = buildElement.child(PLUGINS).orElse(null);
+        Element pluginsElement = buildElement.childElement(PLUGINS).orElse(null);
         if (pluginsElement != null) {
             upgrades += upgradePhaseElementsInPlugins(pluginsElement, phaseUpgrades, context);
         }
 
         // Check pluginManagement section
-        Element pluginManagementElement = buildElement.child(PLUGIN_MANAGEMENT).orElse(null);
+        Element pluginManagementElement =
+                buildElement.childElement(PLUGIN_MANAGEMENT).orElse(null);
         if (pluginManagementElement != null) {
             Element managedPluginsElement =
-                    pluginManagementElement.child(PLUGINS).orElse(null);
+                    pluginManagementElement.childElement(PLUGINS).orElse(null);
             if (managedPluginsElement != null) {
                 upgrades += upgradePhaseElementsInPlugins(managedPluginsElement, phaseUpgrades, context);
             }
@@ -373,16 +375,16 @@ private int upgradePhaseElementsInPlugins(
             Element pluginsElement, Map phaseUpgrades, UpgradeContext context) {
         int upgrades = 0;
 
-        var pluginElements = pluginsElement.children(PLUGIN).toList();
+        var pluginElements = pluginsElement.childElements(PLUGIN).toList();
         for (Element pluginElement : pluginElements) {
-            Element executionsElement = pluginElement.child(EXECUTIONS).orElse(null);
+            Element executionsElement = pluginElement.childElement(EXECUTIONS).orElse(null);
             if (executionsElement != null) {
                 var executionElements = executionsElement
-                        .children(MavenPomElements.Elements.EXECUTION)
+                        .childElements(MavenPomElements.Elements.EXECUTION)
                         .toList();
                 for (Element executionElement : executionElements) {
                     Element phaseElement = executionElement
-                            .child(MavenPomElements.Elements.PHASE)
+                            .childElement(MavenPomElements.Elements.PHASE)
                             .orElse(null);
                     if (phaseElement != null) {
                         String currentPhase = phaseElement.textContent().trim();
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.java
index 783cb1d62110..a40b392c5c1a 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtils.java
@@ -60,7 +60,7 @@ public static String detectModelVersion(Document pomDocument) {
         }
 
         // First try to get from modelVersion element
-        Element modelVersionElement = root.child(MODEL_VERSION).orElse(null);
+        Element modelVersionElement = root.childElement(MODEL_VERSION).orElse(null);
         if (modelVersionElement != null) {
             String modelVersion = modelVersionElement.textContentTrimmed();
             if (!modelVersion.isEmpty()) {
@@ -208,7 +208,7 @@ public static void updateModelVersion(Document pomDocument, String newVersion) {
             return;
         }
 
-        Element modelVersionElement = root.child(MODEL_VERSION).orElse(null);
+        Element modelVersionElement = root.childElement(MODEL_VERSION).orElse(null);
         if (modelVersionElement != null) {
             editor.setTextContent(modelVersionElement, newVersion);
         } else {
@@ -231,9 +231,9 @@ public static boolean removeModelVersion(Document document) {
             return false;
         }
 
-        Element modelVersionElement = root.child(MODEL_VERSION).orElse(null);
+        Element modelVersionElement = root.childElement(MODEL_VERSION).orElse(null);
         if (modelVersionElement != null) {
-            return root.removeNode(modelVersionElement);
+            return root.removeChild(modelVersionElement);
         }
         return false;
     }
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
index e9d145bdc551..a9a14808e076 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategy.java
@@ -195,9 +195,9 @@ private boolean upgradePluginsInDocument(Document pomDocument, UpgradeContext co
         Map pluginUpgrades = getPluginUpgradesMap();
 
         // Check build/plugins
-        Element buildElement = root.child(BUILD).orElse(null);
+        Element buildElement = root.childElement(BUILD).orElse(null);
         if (buildElement != null) {
-            Element pluginsElement = buildElement.child(PLUGINS).orElse(null);
+            Element pluginsElement = buildElement.childElement(PLUGINS).orElse(null);
             if (pluginsElement != null) {
                 hasUpgrades |= upgradePluginsInSection(
                         pluginsElement, pluginUpgrades, pomDocument, BUILD + "/" + PLUGINS, context);
@@ -205,10 +205,10 @@ private boolean upgradePluginsInDocument(Document pomDocument, UpgradeContext co
 
             // Check build/pluginManagement/plugins
             Element pluginManagementElement =
-                    buildElement.child(PLUGIN_MANAGEMENT).orElse(null);
+                    buildElement.childElement(PLUGIN_MANAGEMENT).orElse(null);
             if (pluginManagementElement != null) {
                 Element managedPluginsElement =
-                        pluginManagementElement.child(PLUGINS).orElse(null);
+                        pluginManagementElement.childElement(PLUGINS).orElse(null);
                 if (managedPluginsElement != null) {
                     hasUpgrades |= upgradePluginsInSection(
                             managedPluginsElement,
@@ -260,7 +260,7 @@ private boolean upgradePluginsInSection(
             UpgradeContext context) {
 
         return pluginsElement
-                .children(PLUGIN)
+                .childElements(PLUGIN)
                 .map(pluginElement -> {
                     String groupId = getChildText(pluginElement, GROUP_ID);
                     String artifactId = getChildText(pluginElement, ARTIFACT_ID);
@@ -292,7 +292,7 @@ private boolean upgradePluginVersion(
             Document pomDocument,
             String sectionName,
             UpgradeContext context) {
-        Element versionElement = pluginElement.child(VERSION).orElse(null);
+        Element versionElement = pluginElement.childElement(VERSION).orElse(null);
         String currentVersion;
         boolean isProperty = false;
         String propertyName = null;
@@ -342,10 +342,11 @@ private boolean upgradePropertyVersion(
             UpgradeContext context) {
         Editor editor = new Editor(pomDocument);
         Element root = editor.root();
-        Element propertiesElement = root.child(PROPERTIES).orElse(null);
+        Element propertiesElement = root.childElement(PROPERTIES).orElse(null);
 
         if (propertiesElement != null) {
-            Element propertyElement = propertiesElement.child(propertyName).orElse(null);
+            Element propertyElement =
+                    propertiesElement.childElement(propertyName).orElse(null);
             if (propertyElement != null) {
                 String currentVersion = propertyElement.textContentTrimmed();
                 if (isVersionBelow(currentVersion, upgrade.minVersion)) {
@@ -411,7 +412,7 @@ private boolean isVersionBelow(String currentVersion, String minVersion) {
      * Helper method to get child element text.
      */
     private String getChildText(Element parent, String childName) {
-        Element child = parent.child(childName).orElse(null);
+        Element child = parent.childElement(childName).orElse(null);
         return child != null ? child.textContentTrimmed() : null;
     }
 
@@ -744,7 +745,7 @@ private Path findParentInPomMap(Parent parent, Map pomMap) {
             String version = getChildText(root, VERSION);
 
             // Handle inheritance from parent
-            Element parentElement = root.child(PARENT).orElse(null);
+            Element parentElement = root.childElement(PARENT).orElse(null);
             if (parentElement != null) {
                 if (groupId == null) {
                     groupId = getChildText(parentElement, GROUP_ID);
@@ -775,17 +776,19 @@ private boolean addPluginManagementForEffectivePlugins(
         Element root = pomDocument.root();
 
         // Ensure build/pluginManagement/plugins structure exists
-        Element buildElement = root.child(BUILD).orElse(null);
+        Element buildElement = root.childElement(BUILD).orElse(null);
         if (buildElement == null) {
             buildElement = DomUtils.insertNewElement(BUILD, root);
         }
 
-        Element pluginManagementElement = buildElement.child(PLUGIN_MANAGEMENT).orElse(null);
+        Element pluginManagementElement =
+                buildElement.childElement(PLUGIN_MANAGEMENT).orElse(null);
         if (pluginManagementElement == null) {
             pluginManagementElement = DomUtils.insertNewElement(PLUGIN_MANAGEMENT, buildElement);
         }
 
-        Element managedPluginsElement = pluginManagementElement.child(PLUGINS).orElse(null);
+        Element managedPluginsElement =
+                pluginManagementElement.childElement(PLUGINS).orElse(null);
         if (managedPluginsElement == null) {
             managedPluginsElement = DomUtils.insertNewElement(PLUGINS, pluginManagementElement);
         }
@@ -809,7 +812,7 @@ private boolean addPluginManagementForEffectivePlugins(
      * Checks if a plugin is already managed in the given plugins element.
      */
     private boolean isPluginAlreadyManagedInElement(Element pluginsElement, PluginUpgrade upgrade) {
-        List pluginElements = pluginsElement.children(PLUGIN).toList();
+        List pluginElements = pluginsElement.childElements(PLUGIN).toList();
         for (Element pluginElement : pluginElements) {
             String groupId = getChildText(pluginElement, GROUP_ID);
             String artifactId = getChildText(pluginElement, ARTIFACT_ID);
diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PomDiscovery.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PomDiscovery.java
index f28ef2e4c188..acb764a274b9 100644
--- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PomDiscovery.java
+++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/goals/PomDiscovery.java
@@ -104,13 +104,13 @@ private static void discoverModules(Path baseDirectory, Document parentPom, Map<
         }
 
         // Find modules element
-        Element modulesElement = rootElement.child(MODULES).orElse(null);
+        Element modulesElement = rootElement.childElement(MODULES).orElse(null);
         if (modulesElement == null) {
             return;
         }
 
         // Process each module
-        List moduleElements = modulesElement.children(MODULE).toList();
+        List moduleElements = modulesElement.childElements(MODULE).toList();
         for (Element moduleElement : moduleElements) {
             String moduleName = moduleElement.textContentTrimmed();
             if (moduleName.isEmpty()) {
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
index af8b0774c7ad..52de67e62c88 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/CompatibilityFixStrategyTest.java
@@ -179,7 +179,7 @@ void shouldRemoveDuplicateDependenciesInDependencyManagement() throws Exception
             Element root = editor.root();
             Element dependencyManagement = DomUtils.findChildElement(root, "dependencyManagement");
             Element dependencies = DomUtils.findChildElement(dependencyManagement, "dependencies");
-            var dependencyElements = dependencies.children("dependency").toList();
+            var dependencyElements = dependencies.childElements("dependency").toList();
             assertEquals(1, dependencyElements.size(), "Should have only one dependency after duplicate removal");
         }
 
@@ -223,7 +223,7 @@ void shouldRemoveDuplicateDependenciesInRegularDependencies() throws Exception {
             Editor editor = new Editor(document);
             Element root = editor.root();
             Element dependencies = DomUtils.findChildElement(root, "dependencies");
-            var dependencyElements = dependencies.children("dependency").toList();
+            var dependencyElements = dependencies.childElements("dependency").toList();
             assertEquals(1, dependencyElements.size(), "Should have only one dependency after duplicate removal");
         }
     }
@@ -276,7 +276,7 @@ void shouldRemoveDuplicatePluginsInPluginManagement() throws Exception {
             Element build = DomUtils.findChildElement(root, "build");
             Element pluginManagement = DomUtils.findChildElement(build, "pluginManagement");
             Element plugins = DomUtils.findChildElement(pluginManagement, "plugins");
-            var pluginElements = plugins.children("plugin").toList();
+            var pluginElements = plugins.childElements("plugin").toList();
             assertEquals(1, pluginElements.size(), "Should have only one plugin after duplicate removal");
         }
     }
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtilsTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtilsTest.java
index 3cc4b5e783e6..0fd265c58825 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtilsTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/DomUtilsTest.java
@@ -298,7 +298,7 @@ void testInsertElementInParentWithoutOrdering() throws Exception {
 
         Document doc = Document.of(pomXml);
         Element root = doc.root();
-        Element customParent = root.child("customParent").orElse(null);
+        Element customParent = root.childElement("customParent").orElse(null);
         assertNotNull(customParent, "customParent should exist");
 
         // Insert element in parent that has no ordering defined
@@ -335,9 +335,9 @@ void testInsertElementInDependency() throws Exception {
 
         Document doc = Document.of(pomXml);
         Element root = doc.root();
-        Element dependencies = root.child("dependencies").orElse(null);
+        Element dependencies = root.childElement("dependencies").orElse(null);
         assertNotNull(dependencies, "dependencies should exist");
-        Element dependency = dependencies.child("dependency").orElse(null);
+        Element dependency = dependencies.childElement("dependency").orElse(null);
         assertNotNull(dependency, "dependency should exist");
 
         // Insert elements in dependency according to dependency ordering
@@ -382,7 +382,7 @@ void testInsertElementInBuild() throws Exception {
 
         Document doc = Document.of(pomXml);
         Element root = doc.root();
-        Element build = root.child("build").orElse(null);
+        Element build = root.childElement("build").orElse(null);
         assertNotNull(build, "build should exist");
 
         // Insert elements in build according to build ordering
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/GAVUtilsTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/GAVUtilsTest.java
index 538649feaf07..eb12eb93adef 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/GAVUtilsTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/GAVUtilsTest.java
@@ -209,9 +209,12 @@ void shouldComputeGAVsFromMultiplePOMs() throws Exception {
 
             Set gavs = InferenceStrategy.computeAllArtifactCoordinates(context, pomMap);
 
-            assertEquals(2, gavs.size());
-            assertTrue(gavs.contains(Coordinates.of("com.example", "parent-project", "1.0.0")));
-            assertTrue(gavs.contains(Coordinates.of("com.example", "child-project", "1.0.0")));
+            Set gavStrings = gavs.stream().map(Coordinates::toGAV).collect(java.util.stream.Collectors.toSet());
+            assertEquals(2, gavStrings.size());
+            assertTrue(gavStrings.contains(
+                    Coordinates.of("com.example", "parent-project", "1.0.0").toGAV()));
+            assertTrue(gavStrings.contains(
+                    Coordinates.of("com.example", "child-project", "1.0.0").toGAV()));
         }
 
         @Test
@@ -250,8 +253,10 @@ void shouldDeduplicateIdenticalGAVs() throws Exception {
 
             Set gavs = InferenceStrategy.computeAllArtifactCoordinates(context, pomMap);
 
-            assertEquals(1, gavs.size());
-            assertTrue(gavs.contains(Coordinates.of("com.example", "duplicate-project", "1.0.0")));
+            Set gavStrings = gavs.stream().map(Coordinates::toGAV).collect(java.util.stream.Collectors.toSet());
+            assertEquals(1, gavStrings.size());
+            assertTrue(gavStrings.contains(
+                    Coordinates.of("com.example", "duplicate-project", "1.0.0").toGAV()));
         }
 
         @Test
@@ -287,8 +292,10 @@ void shouldSkipPOMsWithIncompleteGAVs() throws Exception {
 
             Set gavs = InferenceStrategy.computeAllArtifactCoordinates(context, pomMap);
 
-            assertEquals(1, gavs.size());
-            assertTrue(gavs.contains(Coordinates.of("com.example", "valid-project", "1.0.0")));
+            Set gavStrings = gavs.stream().map(Coordinates::toGAV).collect(java.util.stream.Collectors.toSet());
+            assertEquals(1, gavStrings.size());
+            assertTrue(gavStrings.contains(
+                    Coordinates.of("com.example", "valid-project", "1.0.0").toGAV()));
         }
     }
 
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategyTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategyTest.java
index 2fefd68b626e..facedf47ce41 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategyTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/InferenceStrategyTest.java
@@ -319,20 +319,20 @@ void shouldHandlePluginDependencies() throws Exception {
             pomMap.put(Paths.get("project", "module-b", "pom.xml"), moduleBDoc);
 
             Element moduleBRoot = moduleBDoc.root();
-            Element build = moduleBRoot.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
-            Element plugin = plugins.child("plugin").orElse(null);
-            Element dependencies = plugin.child("dependencies").orElse(null);
-            Element dependency = dependencies.child("dependency").orElse(null);
+            Element build = moduleBRoot.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
+            Element plugin = plugins.childElement("plugin").orElse(null);
+            Element dependencies = plugin.childElement("dependencies").orElse(null);
+            Element dependency = dependencies.childElement("dependency").orElse(null);
 
             // Apply dependency inference
             UpgradeContext context = createMockContext();
             strategy.apply(context, pomMap);
 
             // Verify version and groupId were removed from plugin dependency
-            assertNull(dependency.child("version").orElse(null));
-            assertNull(dependency.child("groupId").orElse(null));
-            assertNotNull(dependency.child("artifactId").orElse(null));
+            assertNull(dependency.childElement("version").orElse(null));
+            assertNull(dependency.childElement("groupId").orElse(null));
+            assertNotNull(dependency.childElement("artifactId").orElse(null));
         }
     }
 
@@ -390,10 +390,10 @@ void shouldRemoveParentGroupIdWhenChildDoesntHaveExplicitGroupId() throws Except
             strategy.apply(context, pomMap);
 
             // Verify parent groupId and version were removed (since child doesn't have explicit ones)
-            assertNull(parentElement.child("groupId").orElse(null));
-            assertNull(parentElement.child("version").orElse(null));
+            assertNull(parentElement.childElement("groupId").orElse(null));
+            assertNull(parentElement.childElement("version").orElse(null));
             // artifactId should also be removed since parent POM is in pomMap
-            assertNull(parentElement.child("artifactId").orElse(null));
+            assertNull(parentElement.childElement("artifactId").orElse(null));
         }
 
         @Test
@@ -441,10 +441,10 @@ void shouldKeepParentGroupIdWhenChildHasExplicitGroupId() throws Exception {
             strategy.apply(context, pomMap);
 
             // Verify parent elements are kept (since child has explicit values)
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
             // artifactId should still be removed since parent POM is in pomMap
-            assertNull(parentElement.child("artifactId").orElse(null));
+            assertNull(parentElement.childElement("artifactId").orElse(null));
         }
 
         @Test
@@ -482,9 +482,9 @@ void shouldNotTrimParentElementsWhenParentIsExternal() throws Exception {
             // - artifactId should NOT be removed (external parents need artifactId to be located)
             // - version should NOT be removed (external parents need version to be located)
             // This prevents the "parent.groupId is missing" error reported in issue #7934
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("artifactId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("artifactId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
         }
 
         @Test
@@ -526,7 +526,7 @@ void shouldTrimParentElementsWhenParentIsInReactor() throws Exception {
                     Paths.get("child", "pom.xml"), childDoc);
 
             Element childRoot = childDoc.root();
-            Element parentElement = childRoot.child("parent").orElse(null);
+            Element parentElement = childRoot.childElement("parent").orElse(null);
 
             // Apply inference
             UpgradeContext context = createMockContext();
@@ -536,9 +536,9 @@ void shouldTrimParentElementsWhenParentIsInReactor() throws Exception {
             // - groupId should be removed (child has no explicit groupId, parent is in reactor)
             // - artifactId should be removed (can be inferred from relativePath)
             // - version should be removed (child has no explicit version, parent is in reactor)
-            assertNull(parentElement.child("groupId").orElse(null));
-            assertNull(parentElement.child("artifactId").orElse(null));
-            assertNull(parentElement.child("version").orElse(null));
+            assertNull(parentElement.childElement("groupId").orElse(null));
+            assertNull(parentElement.childElement("artifactId").orElse(null));
+            assertNull(parentElement.childElement("version").orElse(null));
         }
     }
 
@@ -589,25 +589,25 @@ void shouldRemoveChildGroupIdAndVersionWhenTheyMatchParentIn400() throws Excepti
             Element parentElement = DomUtils.findChildElement(childRoot, "parent");
 
             // Verify child and parent elements exist before inference
-            assertNotNull(childRoot.child("groupId").orElse(null));
-            assertNotNull(childRoot.child("version").orElse(null));
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("artifactId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(childRoot.childElement("groupId").orElse(null));
+            assertNotNull(childRoot.childElement("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("artifactId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
 
             // Apply inference
             UpgradeContext context = createMockContext();
             strategy.apply(context, pomMap);
 
             // Verify child groupId and version were removed (Maven 4.0.0 can infer these from parent)
-            assertNull(childRoot.child("groupId").orElse(null));
-            assertNull(childRoot.child("version").orElse(null));
+            assertNull(childRoot.childElement("groupId").orElse(null));
+            assertNull(childRoot.childElement("version").orElse(null));
             // Child artifactId should remain (always required)
-            assertNotNull(childRoot.child("artifactId").orElse(null));
+            assertNotNull(childRoot.childElement("artifactId").orElse(null));
             // Parent elements should all remain (no relativePath inference in 4.0.0)
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("artifactId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("artifactId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
         }
 
         @Test
@@ -649,20 +649,20 @@ void shouldKeepChildGroupIdWhenItDiffersFromParentIn400() throws Exception {
 
             Editor editor = new Editor(childDoc);
             Element childRoot = editor.root();
-            Element parentElement = childRoot.child("parent").orElse(null);
+            Element parentElement = childRoot.childElement("parent").orElse(null);
 
             // Apply inference
             UpgradeContext context = createMockContext();
             strategy.apply(context, pomMap);
 
             // Verify child elements are kept (since they differ from parent)
-            assertNotNull(childRoot.child("groupId").orElse(null));
-            assertNotNull(childRoot.child("version").orElse(null));
-            assertNotNull(childRoot.child("artifactId").orElse(null));
+            assertNotNull(childRoot.childElement("groupId").orElse(null));
+            assertNotNull(childRoot.childElement("version").orElse(null));
+            assertNotNull(childRoot.childElement("artifactId").orElse(null));
             // Parent elements should all remain (no relativePath inference in 4.0.0)
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("artifactId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("artifactId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
         }
 
         @Test
@@ -712,15 +712,15 @@ void shouldHandlePartialInheritanceIn400() throws Exception {
             strategy.apply(context, pomMap);
 
             // Verify child groupId was removed (matches parent, can be inferred)
-            assertNull(childRoot.child("groupId").orElse(null));
+            assertNull(childRoot.childElement("groupId").orElse(null));
             // Verify child version was kept (differs from parent, cannot be inferred)
-            assertNotNull(childRoot.child("version").orElse(null));
+            assertNotNull(childRoot.childElement("version").orElse(null));
             // Verify child artifactId was kept (always required)
-            assertNotNull(childRoot.child("artifactId").orElse(null));
+            assertNotNull(childRoot.childElement("artifactId").orElse(null));
             // Parent elements should all remain (no relativePath inference in 4.0.0)
-            assertNotNull(parentElement.child("groupId").orElse(null));
-            assertNotNull(parentElement.child("artifactId").orElse(null));
-            assertNotNull(parentElement.child("version").orElse(null));
+            assertNotNull(parentElement.childElement("groupId").orElse(null));
+            assertNotNull(parentElement.childElement("artifactId").orElse(null));
+            assertNotNull(parentElement.childElement("version").orElse(null));
         }
 
         @Test
@@ -753,25 +753,25 @@ void shouldNotApplyDependencyInferenceTo400Models() throws Exception {
             Editor editor = new Editor(moduleBDoc);
             Element moduleBRoot = editor.root();
             Element dependency = moduleBRoot
-                    .child("dependencies")
+                    .childElement("dependencies")
                     .orElse(null)
-                    .children("dependency")
+                    .childElements("dependency")
                     .findFirst()
                     .orElse(null);
 
             // Verify dependency elements exist before inference
-            assertNotNull(dependency.child("groupId").orElse(null));
-            assertNotNull(dependency.child("artifactId").orElse(null));
-            assertNotNull(dependency.child("version").orElse(null));
+            assertNotNull(dependency.childElement("groupId").orElse(null));
+            assertNotNull(dependency.childElement("artifactId").orElse(null));
+            assertNotNull(dependency.childElement("version").orElse(null));
 
             // Apply inference
             UpgradeContext context = createMockContext();
             strategy.apply(context, pomMap);
 
             // Verify dependency inference was NOT applied (all elements should remain for 4.0.0)
-            assertNotNull(dependency.child("groupId").orElse(null));
-            assertNotNull(dependency.child("artifactId").orElse(null));
-            assertNotNull(dependency.child("version").orElse(null));
+            assertNotNull(dependency.childElement("groupId").orElse(null));
+            assertNotNull(dependency.childElement("artifactId").orElse(null));
+            assertNotNull(dependency.childElement("version").orElse(null));
         }
     }
 
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategyTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategyTest.java
index 72eb68ebad5d..ea85cefaff12 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategyTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelUpgradeStrategyTest.java
@@ -291,8 +291,8 @@ void shouldConvertModulesToSubprojectsIn410() throws Exception {
             assertNotNull(subprojects);
 
             // Verify module elements were renamed to subproject
-            var moduleElements = subprojects.children("module").toList();
-            var subprojectElements = subprojects.children("subproject").toList();
+            var moduleElements = subprojects.childElements("module").toList();
+            var subprojectElements = subprojects.childElements("subproject").toList();
             assertEquals(0, moduleElements.size());
             assertEquals(2, subprojectElements.size());
 
@@ -473,161 +473,168 @@ private Document createDocumentWithDeprecatedPhases() throws Exception {
 
         private void verifyCleanPluginPhases(Document document) {
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
 
-            Element cleanPlugin = plugins.children("plugin")
+            Element cleanPlugin = plugins.childElements("plugin")
                     .filter(p -> "maven-clean-plugin"
-                            .equals(p.child("artifactId").orElse(null).textContent()))
+                            .equals(p.childElement("artifactId").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(cleanPlugin);
 
-            Element cleanExecutions = cleanPlugin.child("executions").orElse(null);
+            Element cleanExecutions = cleanPlugin.childElement("executions").orElse(null);
             Element preCleanExecution = cleanExecutions
-                    .children("execution")
-                    .filter(e ->
-                            "pre-clean-test".equals(e.child("id").orElse(null).textContent()))
+                    .childElements("execution")
+                    .filter(e -> "pre-clean-test"
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(preCleanExecution);
             assertEquals(
                     "before:clean",
-                    preCleanExecution.child("phase").orElse(null).textContent());
+                    preCleanExecution.childElement("phase").orElse(null).textContent());
 
             Element postCleanExecution = cleanExecutions
-                    .children("execution")
-                    .filter(e ->
-                            "post-clean-test".equals(e.child("id").orElse(null).textContent()))
+                    .childElements("execution")
+                    .filter(e -> "post-clean-test"
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(postCleanExecution);
             assertEquals(
                     "after:clean",
-                    postCleanExecution.child("phase").orElse(null).textContent());
+                    postCleanExecution.childElement("phase").orElse(null).textContent());
         }
 
         private void verifyFailsafePluginPhases(Document document) {
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
 
-            Element failsafePlugin = plugins.children("plugin")
+            Element failsafePlugin = plugins.childElements("plugin")
                     .filter(p -> "maven-failsafe-plugin"
-                            .equals(p.child("artifactId").orElse(null).textContent()))
+                            .equals(p.childElement("artifactId").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(failsafePlugin);
 
-            Element failsafeExecutions = failsafePlugin.child("executions").orElse(null);
+            Element failsafeExecutions =
+                    failsafePlugin.childElement("executions").orElse(null);
             Element preIntegrationExecution = failsafeExecutions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "pre-integration-test-setup"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(preIntegrationExecution);
             assertEquals(
                     "before:integration-test",
-                    preIntegrationExecution.child("phase").orElse(null).textContent());
+                    preIntegrationExecution.childElement("phase").orElse(null).textContent());
 
             Element postIntegrationExecution = failsafeExecutions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "post-integration-test-cleanup"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(postIntegrationExecution);
             assertEquals(
                     "after:integration-test",
-                    postIntegrationExecution.child("phase").orElse(null).textContent());
+                    postIntegrationExecution.childElement("phase").orElse(null).textContent());
         }
 
         private void verifySitePluginPhases(Document document) {
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
 
-            Element sitePlugin = plugins.children("plugin")
+            Element sitePlugin = plugins.childElements("plugin")
                     .filter(p -> "maven-site-plugin"
-                            .equals(p.child("artifactId").orElse(null).textContent()))
+                            .equals(p.childElement("artifactId").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(sitePlugin);
 
-            Element siteExecutions = sitePlugin.child("executions").orElse(null);
+            Element siteExecutions = sitePlugin.childElement("executions").orElse(null);
             Element preSiteExecution = siteExecutions
-                    .children("execution")
-                    .filter(e ->
-                            "pre-site-setup".equals(e.child("id").orElse(null).textContent()))
+                    .childElements("execution")
+                    .filter(e -> "pre-site-setup"
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(preSiteExecution);
             assertEquals(
-                    "before:site", preSiteExecution.child("phase").orElse(null).textContent());
+                    "before:site",
+                    preSiteExecution.childElement("phase").orElse(null).textContent());
 
             Element postSiteExecution = siteExecutions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "post-site-cleanup"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(postSiteExecution);
             assertEquals(
-                    "after:site", postSiteExecution.child("phase").orElse(null).textContent());
+                    "after:site",
+                    postSiteExecution.childElement("phase").orElse(null).textContent());
         }
 
         private void verifyPluginManagementPhases(Document document) {
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element pluginManagement = build.child("pluginManagement").orElse(null);
-            Element managedPlugins = pluginManagement.child("plugins").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element pluginManagement = build.childElement("pluginManagement").orElse(null);
+            Element managedPlugins = pluginManagement.childElement("plugins").orElse(null);
             Element compilerPlugin = managedPlugins
-                    .children("plugin")
+                    .childElements("plugin")
                     .filter(p -> "maven-compiler-plugin"
-                            .equals(p.child("artifactId").orElse(null).textContent()))
+                            .equals(p.childElement("artifactId").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(compilerPlugin);
 
-            Element compilerExecutions = compilerPlugin.child("executions").orElse(null);
+            Element compilerExecutions =
+                    compilerPlugin.childElement("executions").orElse(null);
             Element preCleanCompileExecution = compilerExecutions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "pre-clean-compile"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(preCleanCompileExecution);
             assertEquals(
                     "before:clean",
-                    preCleanCompileExecution.child("phase").orElse(null).textContent());
+                    preCleanCompileExecution.childElement("phase").orElse(null).textContent());
         }
 
         private void verifyProfilePhases(Document document) {
             Element root = document.root();
-            Element profiles = root.child("profiles").orElse(null);
-            Element profile = profiles.child("profile").orElse(null);
-            Element profileBuild = profile.child("build").orElse(null);
-            Element profilePlugins = profileBuild.child("plugins").orElse(null);
+            Element profiles = root.childElement("profiles").orElse(null);
+            Element profile = profiles.childElement("profile").orElse(null);
+            Element profileBuild = profile.childElement("build").orElse(null);
+            Element profilePlugins = profileBuild.childElement("plugins").orElse(null);
             Element antrunPlugin = profilePlugins
-                    .children("plugin")
+                    .childElements("plugin")
                     .filter(p -> "maven-antrun-plugin"
-                            .equals(p.child("artifactId").orElse(null).textContent()))
+                            .equals(p.childElement("artifactId").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(antrunPlugin);
 
-            Element antrunExecutions = antrunPlugin.child("executions").orElse(null);
+            Element antrunExecutions = antrunPlugin.childElement("executions").orElse(null);
             Element profilePreIntegrationExecution = antrunExecutions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "profile-pre-integration-test"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(profilePreIntegrationExecution);
             assertEquals(
                     "before:integration-test",
-                    profilePreIntegrationExecution.child("phase").orElse(null).textContent());
+                    profilePreIntegrationExecution
+                            .childElement("phase")
+                            .orElse(null)
+                            .textContent());
         }
 
         @Test
@@ -677,12 +684,12 @@ void shouldNotUpgradePhasesWhenUpgradingTo400() throws Exception {
 
             // Verify phases were NOT upgraded (should remain as pre-clean)
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
-            Element cleanPlugin = plugins.child("plugin").orElse(null);
-            Element executions = cleanPlugin.child("executions").orElse(null);
-            Element execution = executions.child("execution").orElse(null);
-            Element phase = execution.child("phase").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
+            Element cleanPlugin = plugins.childElement("plugin").orElse(null);
+            Element executions = cleanPlugin.childElement("executions").orElse(null);
+            Element execution = executions.childElement("execution").orElse(null);
+            Element phase = execution.childElement("phase").orElse(null);
 
             assertEquals("pre-clean", phase.textContent(), "Phase should remain as pre-clean for 4.0.0");
         }
@@ -748,39 +755,43 @@ void shouldPreserveNonDeprecatedPhases() throws Exception {
 
             // Verify non-deprecated phases were preserved
             Element root = document.root();
-            Element build = root.child("build").orElse(null);
-            Element plugins = build.child("plugins").orElse(null);
-            Element compilerPlugin = plugins.child("plugin").orElse(null);
-            Element executions = compilerPlugin.child("executions").orElse(null);
+            Element build = root.childElement("build").orElse(null);
+            Element plugins = build.childElement("plugins").orElse(null);
+            Element compilerPlugin = plugins.childElement("plugin").orElse(null);
+            Element executions = compilerPlugin.childElement("executions").orElse(null);
 
             Element compileExecution = executions
-                    .children("execution")
-                    .filter(e ->
-                            "compile-test".equals(e.child("id").orElse(null).textContent()))
+                    .childElements("execution")
+                    .filter(e -> "compile-test"
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(compileExecution);
-            assertEquals("compile", compileExecution.child("phase").orElse(null).textContent());
+            assertEquals(
+                    "compile",
+                    compileExecution.childElement("phase").orElse(null).textContent());
 
             Element testCompileExecution = executions
-                    .children("execution")
+                    .childElements("execution")
                     .filter(e -> "test-compile-test"
-                            .equals(e.child("id").orElse(null).textContent()))
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(testCompileExecution);
             assertEquals(
                     "test-compile",
-                    testCompileExecution.child("phase").orElse(null).textContent());
+                    testCompileExecution.childElement("phase").orElse(null).textContent());
 
             Element packageExecution = executions
-                    .children("execution")
-                    .filter(e ->
-                            "package-test".equals(e.child("id").orElse(null).textContent()))
+                    .childElements("execution")
+                    .filter(e -> "package-test"
+                            .equals(e.childElement("id").orElse(null).textContent()))
                     .findFirst()
                     .orElse(null);
             assertNotNull(packageExecution);
-            assertEquals("package", packageExecution.child("phase").orElse(null).textContent());
+            assertEquals(
+                    "package",
+                    packageExecution.childElement("phase").orElse(null).textContent());
         }
     }
 
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtilsTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtilsTest.java
index cd5e1f0d145e..4047d9c95249 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtilsTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/ModelVersionUtilsTest.java
@@ -295,7 +295,7 @@ void shouldUpdateModelVersionInDocument(String targetVersion) throws Exception {
             Document document = new Parser().parse(pomXml);
             ModelVersionUtils.updateModelVersion(document, targetVersion);
             Element root = document.root();
-            Element modelVersionElement = root.child("modelVersion").orElse(null);
+            Element modelVersionElement = root.childElement("modelVersion").orElse(null);
             assertEquals(targetVersion, modelVersionElement.textContentTrimmed());
         }
 
@@ -315,7 +315,7 @@ void shouldAddModelVersionWhenMissing(String targetVersion) throws Exception {
             Document document = Document.of(pomXml);
             ModelVersionUtils.updateModelVersion(document, targetVersion);
             Element root = document.root();
-            Element modelVersionElement = root.child("modelVersion").orElse(null);
+            Element modelVersionElement = root.childElement("modelVersion").orElse(null);
             assertNotNull(modelVersionElement);
             assertEquals(targetVersion, modelVersionElement.textContentTrimmed());
         }
@@ -338,7 +338,7 @@ void shouldRemoveModelVersionFromDocument() throws Exception {
 
             assertTrue(result);
             Element root = document.root();
-            Element modelVersionElement = root.child(MODEL_VERSION).orElse(null);
+            Element modelVersionElement = root.childElement(MODEL_VERSION).orElse(null);
             assertNull(modelVersionElement);
         }
 
diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
index 49abdf2be51a..931b0560f7cd 100644
--- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
+++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/PluginUpgradeStrategyTest.java
@@ -449,10 +449,10 @@ void shouldAddPluginManagementBeforeExistingPluginsSection() throws Exception {
             // Verify the structure
             Editor editor = new Editor(document);
             Element root = editor.root();
-            Element buildElement = root.child("build").orElse(null);
+            Element buildElement = root.childElement("build").orElse(null);
             assertNotNull(buildElement, "Build element should exist");
 
-            List buildChildren = buildElement.children().toList();
+            List buildChildren = buildElement.childElements().toList();
 
             // Find the indices of pluginManagement and plugins
             int pluginManagementIndex = -1;
diff --git a/pom.xml b/pom.xml
index afedf3564fba..ea0c5289682d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -146,7 +146,7 @@ under the License.
     1.18.8
     2.9.0
     1.11.0
-    0.4.1
+    1.3.0
     5.1.0
     33.6.0-jre
     1.0.1