diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/AddOrUpdateChildTag.java b/rewrite-xml/src/main/java/org/openrewrite/xml/AddOrUpdateChildTag.java
new file mode 100644
index 00000000000..5b44051649c
--- /dev/null
+++ b/rewrite-xml/src/main/java/org/openrewrite/xml/AddOrUpdateChildTag.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2022 the original author or authors.
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * https://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.xml;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+import org.intellij.lang.annotations.Language;
+import org.jspecify.annotations.Nullable;
+import org.openrewrite.*;
+import org.openrewrite.xml.tree.Xml;
+
+@Value
+@EqualsAndHashCode(callSuper = false)
+public class AddOrUpdateChildTag extends Recipe {
+
+    @Option(displayName = "Parent XPath",
+            description = "XPath identifying the parent to which a child tag must be added",
+            example = "/project//plugin//configuration")
+    @Language("xpath")
+    String parentXPath;
+
+    @Option(displayName = "New child tag",
+            description = "The XML of the new child to add or update on the parent tag.",
+            example = "<skip>true</skip>")
+    @Language("xml")
+    String newChildTag;
+
+    @Option(displayName = "Replace existing child",
+            description = "Set to `false` to not replace the child tag if it already exists. Defaults to true.",
+            required = false)
+    @Nullable
+    Boolean replaceExisting;
+
+    @Override
+    public String getDisplayName() {
+        return "Add or update child tag";
+    }
+
+    @Override
+    public String getDescription() {
+        return "Adds or updates a child element below the parent(s) matching the provided `parentXPath` expression. " +
+               "If a child with the same name already exists, it will be replaced by default. Otherwise, a new child will be added. " +
+               "This ensures idempotent behaviour.";
+    }
+
+    @Override
+    public Validated<Object> validate() {
+        Validated<Object> validated = super.validate()
+                .and(Validated.notBlank("parentXPath", parentXPath))
+                .and(Validated.notBlank("newChildTag", newChildTag));
+        try {
+            Xml.Tag.build(newChildTag);
+        } catch (Exception e) {
+            validated = validated.and(Validated.invalid("newChildTag", newChildTag, "Invalid XML for child tag", e));
+        }
+        return validated;
+    }
+
+    @Override
+    public TreeVisitor<?, ExecutionContext> getVisitor() {
+        return new XmlVisitor<ExecutionContext>() {
+            private final XPathMatcher xPathMatcher = new XPathMatcher(parentXPath);
+
+            @Override
+            public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
+                if (xPathMatcher.matches(getCursor())) {
+                    Xml.Tag newChild = Xml.Tag.build(newChildTag);
+                    if (replaceExisting == null || replaceExisting || !tag.getChild(newChild.getName()).isPresent()) {
+                        return AddOrUpdateChild.addOrUpdateChild(tag, newChild, getCursor().getParentOrThrow());
+                    }
+                }
+                return super.visitTag(tag, ctx);
+            }
+        };
+    }
+}
diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/XPathMatcher.java b/rewrite-xml/src/main/java/org/openrewrite/xml/XPathMatcher.java
index b3c184b9038..c3fbd8fe165 100644
--- a/rewrite-xml/src/main/java/org/openrewrite/xml/XPathMatcher.java
+++ b/rewrite-xml/src/main/java/org/openrewrite/xml/XPathMatcher.java
@@ -48,12 +48,14 @@ public class XPathMatcher {
     private final boolean startsWithSlash;
     private final boolean startsWithDoubleSlash;
     private final String[] parts;
+    private final long tagMatchingParts;
 
     public XPathMatcher(String expression) {
         this.expression = expression;
         startsWithSlash = expression.startsWith("/");
         startsWithDoubleSlash = expression.startsWith("//");
         parts = splitOnXPathSeparator(expression.substring(startsWithDoubleSlash ? 2 : startsWithSlash ? 1 : 0));
+        tagMatchingParts = Arrays.stream(parts).filter(part -> !part.isEmpty() && !part.startsWith("@")).count();
     }
 
     private String[] splitOnXPathSeparator(String input) {
@@ -92,18 +94,8 @@ public boolean matches(Cursor cursor) {
                     if (index < 0) {
                         return false;
                     }
-                    if (part.startsWith("@")) { // is attribute selector
-                        partWithCondition = part;
-                        tagForCondition = i > 0 ? path.get(i - 1) : path.get(i);
-                    } else { // is element selector
-                        if (part.charAt(index + 1) == '@') { // is Attribute condition
-                            partWithCondition = part;
-                            tagForCondition = path.get(i);
-                        } else if (part.contains("(") && part.contains(")")) { // is function condition
-                            partWithCondition = part;
-                            tagForCondition = path.get(i);
-                        }
-                    }
+                    partWithCondition = part;
+                    tagForCondition = path.get(pathIndex);
                 } else if (i < path.size() && i > 0 && parts[i - 1].endsWith("]")) {
                     String partBefore = parts[i - 1];
                     int index = partBefore.indexOf("[");
@@ -117,6 +109,7 @@ public boolean matches(Cursor cursor) {
                     }
                 } else if (part.endsWith(")")) { // is xpath method
                     // TODO: implement other xpath methods
+                    throw new UnsupportedOperationException("XPath methods are not supported");
                 }
 
                 String partName;
@@ -164,36 +157,42 @@ public boolean matches(Cursor cursor) {
                 }
             }
 
-            return startsWithSlash || path.size() - pathIndex <= 1;
+            // we have matched the whole XPath, and it does not start with the root
+            return true;
         } else {
             Collections.reverse(path);
 
             // Deal with the two forward slashes in the expression; works, but I'm not proud of it.
-            if (expression.contains("//") && !expression.contains("://") && Arrays.stream(parts).anyMatch(StringUtils::isBlank)) {
+            if (expression.contains("//") && Arrays.stream(parts).anyMatch(StringUtils::isBlank)) {
                 int blankPartIndex = Arrays.asList(parts).indexOf("");
                 int doubleSlashIndex = expression.indexOf("//");
 
-                if (path.size() > blankPartIndex && path.size() >= parts.length - 1) {
-                    String newExpression;
-                    if (Objects.equals(path.get(blankPartIndex).getName(), parts[blankPartIndex + 1])) {
-                        newExpression = String.format(
-                                "%s/%s",
-                                expression.substring(0, doubleSlashIndex),
-                                expression.substring(doubleSlashIndex + 2)
-                        );
-                    } else {
-                        newExpression = String.format(
-                                "%s/%s/%s",
-                                expression.substring(0, doubleSlashIndex),
-                                path.get(blankPartIndex).getName(),
-                                expression.substring(doubleSlashIndex + 2)
-                        );
+                if (path.size() > blankPartIndex && path.size() >= tagMatchingParts) {
+                    Xml.Tag blankPartTag = path.get(blankPartIndex);
+                    String part = parts[blankPartIndex + 1];
+                    Matcher matcher = ELEMENT_WITH_CONDITION_PATTERN.matcher(part);
+                    if (matcher.matches() ?
+                            matchesElementWithConditionFunction(matcher, blankPartTag, cursor) != null :
+                            Objects.equals(blankPartTag.getName(), part)) {
+                        if (matchesWithoutDoubleSlashesAt(cursor, doubleSlashIndex)) {
+                            return true;
+                        }
+                        // fall-through: maybe we can skip this element and match further down
                     }
+                    String newExpression = String.format(
+                            // the // here allows to skip several levels of nested elements
+                            "%s/%s//%s",
+                            expression.substring(0, doubleSlashIndex),
+                            blankPartTag.getName(),
+                            expression.substring(doubleSlashIndex + 2)
+                    );
                     return new XPathMatcher(newExpression).matches(cursor);
+                } else if (path.size() == tagMatchingParts) {
+                    return matchesWithoutDoubleSlashesAt(cursor, doubleSlashIndex);
                 }
             }
 
-            if (parts.length > path.size() + 1) {
+            if (tagMatchingParts > path.size()) {
                 return false;
             }
 
@@ -235,6 +234,24 @@ public boolean matches(Cursor cursor) {
         }
     }
 
+    private boolean matchesWithoutDoubleSlashesAt(Cursor cursor, int doubleSlashIndex) {
+        String newExpression = String.format(
+                "%s/%s",
+                expression.substring(0, doubleSlashIndex),
+                expression.substring(doubleSlashIndex + 2)
+        );
+        return new XPathMatcher(newExpression).matches(cursor);
+    }
+
+    /**
+     * Checks that the given {@code tag} matches the XPath part represented by {@code matcher}.
+     *
+     * @param matcher an XPath part matcher for {@link #ELEMENT_WITH_CONDITION_PATTERN}
+     * @param tag     a tag to match
+     * @param cursor  the cursor we are trying to match
+     * @return the element name specified before the condition of the part
+     * (either {@code tag.getName()}, {@code "*"} or an attribute name) or {@code null} if the tag did not match
+     */
     private @Nullable String matchesElementWithConditionFunction(Matcher matcher, Xml.Tag tag, Cursor cursor) {
         boolean isAttributeElement = matcher.group(1) != null;
         String element = matcher.group(2);
diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/AddOrUpdateChildTagTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/AddOrUpdateChildTagTest.java
new file mode 100644
index 00000000000..49bdce28b09
--- /dev/null
+++ b/rewrite-xml/src/test/java/org/openrewrite/xml/AddOrUpdateChildTagTest.java
@@ -0,0 +1,496 @@
+/*
+ * Copyright 2024 the original author or authors.
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * https://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openrewrite.xml;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.NullSource;
+import org.openrewrite.test.RewriteTest;
+
+import static org.openrewrite.xml.Assertions.xml;
+
+class AddOrUpdateChildTagTest implements RewriteTest {
+    @ParameterizedTest
+    @NullSource
+    @CsvSource({"true", "false"})
+    void addsTagEverywhereWhenAbsent(Boolean replaceExisting) {
+        rewriteRun(spec -> spec.recipe(new AddOrUpdateChildTag(
+                        "/project//plugin[groupId='org.apache.maven.plugins' and artifactId='maven-resources-plugin']" +
+                        "//configuration",
+                        "<skip>true</skip>",
+                        replaceExisting)),
+                xml(
+                        """
+                                <?xml version="1.0" encoding="UTF-8"?>
+                                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                                    <modelVersion>4.0.0</modelVersion>
+                                    <groupId>com.example</groupId>
+                                    <artifactId>my-project</artifactId>
+                                    <version>1.0</version>
+                                
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                    <configuration>
+                                                        <encoding>UTF-8</encoding>
+                                                    </configuration>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-resources-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <executions>
+                                                    <execution>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                        </configuration>
+                                                    </execution>
+                                                </executions>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                    <profiles>
+                                        <profile>
+                                            <id>profile1</id>
+                                            <build>
+                                                <pluginManagement>
+                                                    <plugins>
+                                                        <plugin>
+                                                            <groupId>org.apache.maven.plugins</groupId>
+                                                            <artifactId>maven-resources-plugin</artifactId>
+                                                            <version>3.3.1</version>
+                                                            <executions>
+                                                                <execution>
+                                                                    <configuration>
+                                                                        <encoding>UTF-8</encoding>
+                                                                    </configuration>
+                                                                </execution>
+                                                            </executions>
+                                                        </plugin>
+                                                    </plugins>
+                                                </pluginManagement>
+                                                <plugins>
+                                                    <plugin>
+                                                        <groupId>org.apache.maven.plugins</groupId>
+                                                        <artifactId>maven-resources-plugin</artifactId>
+                                                        <version>3.3.1</version>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                        </configuration>
+                                                    </plugin>
+                                                </plugins>
+                                            </build>
+                                        </profile>
+                                    </profiles>
+                                </project>
+                                """,
+                        """
+                                <?xml version="1.0" encoding="UTF-8"?>
+                                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                                    <modelVersion>4.0.0</modelVersion>
+                                    <groupId>com.example</groupId>
+                                    <artifactId>my-project</artifactId>
+                                    <version>1.0</version>
+                                
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                    <configuration>
+                                                        <encoding>UTF-8</encoding>
+                                                        <skip>true</skip>
+                                                    </configuration>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-resources-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <executions>
+                                                    <execution>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                            <skip>true</skip>
+                                                        </configuration>
+                                                    </execution>
+                                                </executions>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                    <profiles>
+                                        <profile>
+                                            <id>profile1</id>
+                                            <build>
+                                                <pluginManagement>
+                                                    <plugins>
+                                                        <plugin>
+                                                            <groupId>org.apache.maven.plugins</groupId>
+                                                            <artifactId>maven-resources-plugin</artifactId>
+                                                            <version>3.3.1</version>
+                                                            <executions>
+                                                                <execution>
+                                                                    <configuration>
+                                                                        <encoding>UTF-8</encoding>
+                                                                        <skip>true</skip>
+                                                                    </configuration>
+                                                                </execution>
+                                                            </executions>
+                                                        </plugin>
+                                                    </plugins>
+                                                </pluginManagement>
+                                                <plugins>
+                                                    <plugin>
+                                                        <groupId>org.apache.maven.plugins</groupId>
+                                                        <artifactId>maven-resources-plugin</artifactId>
+                                                        <version>3.3.1</version>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                            <skip>true</skip>
+                                                        </configuration>
+                                                    </plugin>
+                                                </plugins>
+                                            </build>
+                                        </profile>
+                                    </profiles>
+                                </project>
+                                """
+                )
+        );
+    }
+
+    @ParameterizedTest
+    @NullSource
+    @CsvSource("true")
+    void updateTagEverywhere(Boolean replaceExisting) {
+        rewriteRun(spec -> spec.recipe(new AddOrUpdateChildTag(
+                        "/project//plugin[groupId='org.apache.maven.plugins' and artifactId='maven-resources-plugin']" +
+                        "//configuration",
+                        "<skip>true</skip>",
+                        replaceExisting)),
+                xml(
+                        """
+                                <?xml version="1.0" encoding="UTF-8"?>
+                                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                                    <modelVersion>4.0.0</modelVersion>
+                                    <groupId>com.example</groupId>
+                                    <artifactId>my-project</artifactId>
+                                    <version>1.0</version>
+                                
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                    <configuration>
+                                                        <encoding>UTF-8</encoding>
+                                                        <skip>false</skip>
+                                                    </configuration>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-resources-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <configuration>
+                                                    <encoding>UTF-8</encoding>
+                                                    <skip>false</skip>
+                                                </configuration>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                    <profiles>
+                                        <profile>
+                                            <id>profile1</id>
+                                            <build>
+                                                <pluginManagement>
+                                                    <plugins>
+                                                        <plugin>
+                                                            <groupId>org.apache.maven.plugins</groupId>
+                                                            <artifactId>maven-resources-plugin</artifactId>
+                                                            <version>3.3.1</version>
+                                                            <configuration>
+                                                                <encoding>UTF-8</encoding>
+                                                                <skip>false</skip>
+                                                            </configuration>
+                                                        </plugin>
+                                                    </plugins>
+                                                </pluginManagement>
+                                                <plugins>
+                                                    <plugin>
+                                                        <groupId>org.apache.maven.plugins</groupId>
+                                                        <artifactId>maven-resources-plugin</artifactId>
+                                                        <version>3.3.1</version>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                            <skip>false</skip>
+                                                        </configuration>
+                                                    </plugin>
+                                                </plugins>
+                                            </build>
+                                        </profile>
+                                    </profiles>
+                                </project>
+                                """,
+                        """
+                                <?xml version="1.0" encoding="UTF-8"?>
+                                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                                    <modelVersion>4.0.0</modelVersion>
+                                    <groupId>com.example</groupId>
+                                    <artifactId>my-project</artifactId>
+                                    <version>1.0</version>
+                                
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                    <configuration>
+                                                        <encoding>UTF-8</encoding>
+                                                        <skip>true</skip>
+                                                    </configuration>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-resources-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <configuration>
+                                                    <encoding>UTF-8</encoding>
+                                                    <skip>true</skip>
+                                                </configuration>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                    <profiles>
+                                        <profile>
+                                            <id>profile1</id>
+                                            <build>
+                                                <pluginManagement>
+                                                    <plugins>
+                                                        <plugin>
+                                                            <groupId>org.apache.maven.plugins</groupId>
+                                                            <artifactId>maven-resources-plugin</artifactId>
+                                                            <version>3.3.1</version>
+                                                            <configuration>
+                                                                <encoding>UTF-8</encoding>
+                                                                <skip>true</skip>
+                                                            </configuration>
+                                                        </plugin>
+                                                    </plugins>
+                                                </pluginManagement>
+                                                <plugins>
+                                                    <plugin>
+                                                        <groupId>org.apache.maven.plugins</groupId>
+                                                        <artifactId>maven-resources-plugin</artifactId>
+                                                        <version>3.3.1</version>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                            <skip>true</skip>
+                                                        </configuration>
+                                                    </plugin>
+                                                </plugins>
+                                            </build>
+                                        </profile>
+                                    </profiles>
+                                </project>
+                                """
+                )
+        );
+    }
+
+    @Test
+    void dontUpdateIfReplaceIsDisabled() {
+        rewriteRun(spec -> spec.recipe(new AddOrUpdateChildTag(
+                        "/project//plugin[groupId='org.apache.maven.plugins' and artifactId='maven-resources-plugin']" +
+                        "//configuration",
+                        "<skip>true</skip>",
+                        false)),
+                xml(
+                        """
+                                <?xml version="1.0" encoding="UTF-8"?>
+                                <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                                    <modelVersion>4.0.0</modelVersion>
+                                    <groupId>com.example</groupId>
+                                    <artifactId>my-project</artifactId>
+                                    <version>1.0</version>
+                                
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                    <configuration>
+                                                        <encoding>UTF-8</encoding>
+                                                        <skip>false</skip>
+                                                    </configuration>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-resources-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <configuration>
+                                                    <encoding>UTF-8</encoding>
+                                                    <skip>false</skip>
+                                                </configuration>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                    <profiles>
+                                        <profile>
+                                            <id>profile1</id>
+                                            <build>
+                                                <pluginManagement>
+                                                    <plugins>
+                                                        <plugin>
+                                                            <groupId>org.apache.maven.plugins</groupId>
+                                                            <artifactId>maven-resources-plugin</artifactId>
+                                                            <version>3.3.1</version>
+                                                            <configuration>
+                                                                <encoding>UTF-8</encoding>
+                                                                <skip>false</skip>
+                                                            </configuration>
+                                                        </plugin>
+                                                    </plugins>
+                                                </pluginManagement>
+                                                <plugins>
+                                                    <plugin>
+                                                        <groupId>org.apache.maven.plugins</groupId>
+                                                        <artifactId>maven-resources-plugin</artifactId>
+                                                        <version>3.3.1</version>
+                                                        <configuration>
+                                                            <encoding>UTF-8</encoding>
+                                                            <skip>false</skip>
+                                                        </configuration>
+                                                    </plugin>
+                                                </plugins>
+                                            </build>
+                                        </profile>
+                                    </profiles>
+                                </project>
+                                """
+                )
+        );
+    }
+
+    @ParameterizedTest
+    @NullSource
+    @CsvSource({"true", "false"})
+    void dontTouchAnythingElse(Boolean replaceExisting) {
+        rewriteRun(spec -> spec.recipe(new AddOrUpdateChildTag(
+                        "/project//plugin[groupId='org.apache.maven.plugins' and artifactId='maven-resources-plugin']" +
+                        "//configuration",
+                        "<skip>true</skip>",
+                        replaceExisting)),
+                xml(
+                        """
+                        <?xml version="1.0" encoding="UTF-8"?>
+                        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+                            <modelVersion>4.0.0</modelVersion>
+                            <groupId>com.example</groupId>
+                            <artifactId>my-project</artifactId>
+                            <version>1.0</version>
+                        
+                            <build>
+                                <pluginManagement>
+                                    <plugins>
+                                        <plugin>
+                                            <groupId>org.apache.maven.plugins</groupId>
+                                            <artifactId>maven-other-plugin</artifactId>
+                                            <version>3.3.1</version>
+                                            <configuration>
+                                                <encoding>UTF-8</encoding>
+                                                <skip>false</skip>
+                                            </configuration>
+                                        </plugin>
+                                    </plugins>
+                                </pluginManagement>
+                                <plugins>
+                                    <plugin>
+                                        <groupId>org.apache.other.plugins</groupId>
+                                        <artifactId>maven-resources-plugin</artifactId>
+                                        <version>3.3.1</version>
+                                        <configuration>
+                                            <encoding>UTF-8</encoding>
+                                            <skip>false</skip>
+                                        </configuration>
+                                    </plugin>
+                                </plugins>
+                            </build>
+                            <profiles>
+                                <profile>
+                                    <id>profile1</id>
+                                    <build>
+                                        <pluginManagement>
+                                            <plugins>
+                                                <plugin>
+                                                    <groupId>org.apache.maven.plugins</groupId>
+                                                    <artifactId>maven-resources-plugin</artifactId>
+                                                    <version>3.3.1</version>
+                                                </plugin>
+                                            </plugins>
+                                        </pluginManagement>
+                                        <plugins>
+                                            <plugin>
+                                                <groupId>org.apache.maven.plugins</groupId>
+                                                <artifactId>maven-other-plugin</artifactId>
+                                                <version>3.3.1</version>
+                                                <configuration>
+                                                    <encoding>UTF-8</encoding>
+                                                    <skip>false</skip>
+                                                </configuration>
+                                            </plugin>
+                                        </plugins>
+                                    </build>
+                                </profile>
+                            </profiles>
+                        </project>
+                        """
+                )
+        );
+    }
+}
diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/XPathMatcherTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/XPathMatcherTest.java
index f369bfda2c2..31b5363800b 100755
--- a/rewrite-xml/src/test/java/org/openrewrite/xml/XPathMatcherTest.java
+++ b/rewrite-xml/src/test/java/org/openrewrite/xml/XPathMatcherTest.java
@@ -118,7 +118,13 @@ void matchAbsolute() {
         assertThat(match("/dependencies/dependency", xmlDoc)).isTrue();
         assertThat(match("/dependencies/*/artifactId", xmlDoc)).isTrue();
         assertThat(match("/dependencies/*", xmlDoc)).isTrue();
+        assertThat(match("/dependencies//dependency", xmlDoc)).isTrue();
+        assertThat(match("/dependencies//dependency//groupId", xmlDoc)).isTrue();
+
+        // negative matches
         assertThat(match("/dependencies/dne", xmlDoc)).isFalse();
+        assertThat(match("/dependencies//dne", xmlDoc)).isFalse();
+        assertThat(match("/dependencies//dependency//dne", xmlDoc)).isFalse();
     }
 
     @Test
@@ -127,6 +133,17 @@ void matchAbsoluteAttribute() {
         assertThat(match("/dependencies/dependency/artifactId/@scope", xmlDoc)).isTrue();
         assertThat(match("/dependencies/dependency/artifactId/@*", xmlDoc)).isTrue();
         assertThat(match("/dependencies/dependency/groupId/@*", xmlDoc)).isFalse();
+        assertThat(match("/dependencies//dependency//@scope", xmlDoc)).isTrue();
+        assertThat(match("/dependencies//dependency//artifactId//@scope", xmlDoc)).isTrue();
+        assertThat(match("/dependencies//dependency//@*", xmlDoc)).isTrue();
+        assertThat(match("/dependencies//dependency//artifactId//@*", xmlDoc)).isTrue();
+
+        // negative matches
+        assertThat(match("/dependencies/dependency/artifactId/@dne", xmlDoc)).isFalse();
+        assertThat(match("/dependencies/dependency/artifactId/@dne", xmlDoc)).isFalse();
+        assertThat(match("/dependencies//dependency//@dne", xmlDoc)).isFalse();
+        assertThat(match("/dependencies//dependency//artifactId//@dne", xmlDoc)).isFalse();
+
     }
 
     @Test
@@ -136,8 +153,6 @@ void matchRelative() {
         assertThat(match("//dependency", xmlDoc)).isTrue();
         assertThat(match("dependency/*", xmlDoc)).isTrue();
         assertThat(match("dne", xmlDoc)).isFalse();
-        assertThat(match("/dependencies//dependency", xmlDoc)).isTrue();
-        assertThat(match("/dependencies//dependency/groupId", xmlDoc)).isTrue();
     }
 
     @Test
@@ -147,6 +162,51 @@ void matchRelativeAttribute() {
         assertThat(match("//dependency/artifactId/@scope", xmlDoc)).isTrue();
     }
 
+    @Test
+    void matchNestedElementsWithSameName() {
+        var xml = new XmlParser().parse(
+          """
+            <?xml version="1.0" encoding="UTF-8"?>
+            <root>
+                <element foo="bar">
+                    <element foo="bar">
+                        <test>auie</test>
+                    </element>
+                    <element qux="quux" />
+                </element>
+            </root>
+            """
+        ).toList().get(0);
+
+        // no / at start
+        assertThat(match("element/test", xml)).isTrue();
+        assertThat(match("element[@foo='bar']/test", xml)).isTrue();
+        assertThat(match("element[@foo='baz']/test", xml)).isFalse();
+        assertThat(match("element/@qux", xml)).isTrue();
+        assertThat(match("dne[@foo='bar']/test", xml)).isFalse();
+
+        // // at start
+        assertThat(match("//element/test", xml)).isTrue();
+        assertThat(match("//element[@foo='bar']/test", xml)).isTrue();
+        assertThat(match("//element[@foo='baz']/test", xml)).isFalse();
+        assertThat(match("//element/@qux", xml)).isTrue();
+        assertThat(match("//dne[@foo='bar']/test", xml)).isFalse();
+
+        // TODO // in the middle without / (or with //) at start (not currently supported)
+//        assertThat(match("root//element/test", xml)).isTrue();
+//        assertThat(match("root//element[@foo='bar']/test", xml)).isTrue();
+//        assertThat(match("root//element[@foo='baz']/test", xml)).isFalse();
+//        assertThat(match("root//element/@qux", xml)).isTrue();
+//        assertThat(match("root//dne[@foo='bar']/test", xml)).isFalse();
+
+        // // in the middle with / at start
+        assertThat(match("/root//element/test", xml)).isTrue();
+        assertThat(match("/root//element[@foo='bar']/test", xml)).isTrue();
+        assertThat(match("/root//element[@foo='baz']/test", xml)).isFalse();
+        assertThat(match("/root//element/@qux", xml)).isTrue();
+        assertThat(match("/root//dne[@foo='bar']/test", xml)).isFalse();
+    }
+
     @Test
     void matchPom() {
         assertThat(match("/project/build/plugins/plugin/configuration/source",
@@ -163,8 +223,10 @@ void matchPom() {
           pomXml1)).isTrue();
         assertThat(match("/project/build//plugins/plugin/configuration/source",
           pomXml2)).isTrue();
-//        assertThat(match("/project/build//plugin/configuration/source", pomXml2)).isTrue(); // TODO: seems parser only handles // up to 1 level
-//        assertThat(match("/project//configuration/source", pomXml2)).isTrue(); // TODO: was already failing previously
+        // skip 2+ levels with //
+        assertThat(match("/project/build//plugin/configuration/source", pomXml2)).isTrue();
+        assertThat(match("/project//configuration/source", pomXml2)).isTrue();
+        assertThat(match("/project//plugin//source", pomXml2)).isTrue();
     }
 
     private final SourceFile attributeXml = new XmlParser().parse(
@@ -203,7 +265,7 @@ void wildcards() {
         // relative xpath with wildcard element
         assertThat(match("//*[@foo='bar']", attributeXml)).isTrue();
         assertThat(match("//*[@foo='baz']", attributeXml)).isFalse();
-//        assertThat(match("//*[foo='bar']", attributeXml)).isFalse(); // TODO: fix relative xpath with condition
+        assertThat(match("//*[foo='bar']", attributeXml)).isFalse();
         assertThat(match("//*[foo='baz']", attributeXml)).isTrue();
     }
 
@@ -220,7 +282,7 @@ void relativePathsWithConditions() {
             </root>
             """
         ).toList().get(0);
-//        assertThat(match("//element1[foo='bar']", xml)).isFalse(); // TODO: fix - was already failing before * changes
+        assertThat(match("//element1[foo='bar']", xml)).isFalse();
         assertThat(match("//element1[foo='baz']", xml)).isTrue();
         assertThat(match("//element1[@foo='bar']", xml)).isTrue();
         assertThat(match("//element1[foo='baz']/test", xml)).isTrue();
@@ -275,8 +337,7 @@ void matchLocalNameFunctionCondition() {
         assertThat(match("//ns2:element2[local-name()='element2']", namespacedXml)).isTrue();
         assertThat(match("//dne[local-name()='dne']", namespacedXml)).isFalse();
 
-        // TODO: fix mid-path // with condition
-//        assertThat(match("/root//element1[local-name()='element1']", namespacedXml)).isTrue();
+        assertThat(match("/root//element1[local-name()='element1']", namespacedXml)).isTrue();
     }
 
     @Test
@@ -300,9 +361,8 @@ void matchAttributeCondition() {
         assertThat(match("//element1[@*='dne']", namespacedXml)).isFalse();
         assertThat(match("/root/element1[@*='content3']", namespacedXml)).isTrue();
         assertThat(match("/root/element1[@*='dne']", namespacedXml)).isFalse();
-        // TODO: fix mid-path // match with condition
-//        assertThat(match("/root//element1[@*='content3']", namespacedXml)).isTrue();
-//        assertThat(match("/root//element1[@*='dne']", namespacedXml)).isFalse();
+        assertThat(match("/root//element1[@*='content3']", namespacedXml)).isTrue();
+        assertThat(match("/root//element1[@*='dne']", namespacedXml)).isFalse();
     }
 
     @Test
@@ -327,9 +387,8 @@ void matchAttributeElement() {
         assertThat(match("/root/parent/element3/@ns3:attr[namespace-uri()='http://www.example.com/namespace3']", namespacedXml)).isTrue();
         assertThat(match("//element3/@ns3:attr[namespace-uri()='http://www.example.com/namespace3']", namespacedXml)).isTrue();
 
-        // TODO: fix mid-path // match with attribute element
-//        assertThat(match("/root//element1/@*", namespacedXml)).isTrue();
-//        assertThat(match("/root//element1/@*[namespace-uri()='http://www.example.com/namespace3']", namespacedXml)).isTrue();
+        assertThat(match("/root//element1/@*", namespacedXml)).isTrue();
+        assertThat(match("/root//element1/@*[namespace-uri()='http://www.example.com/namespace3']", namespacedXml)).isTrue();
     }
 
     @Test