You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT无法一次性为Maven的pom.xml插入两个缺失节点求助

解决Maven POM的XSLT一次性插入多个缺失节点的问题

你现在遇到的问题很典型:你的XSLT把插入distributionManagement和profiles的逻辑拆成了两个独立的模板,当目标pom里两个节点都不存在时,XSLT处理器只会触发其中一个模板(因为两个模板匹配的是同一个project节点,且优先级完全相同,处理器会默认选择排在前面的那个),所以第一次运行只插入distributionManagement,第二次运行时这个节点已经存在了,才会触发第二个模板插入profiles。

问题根源

XSLT的模板匹配规则中,当多个模板对同一个节点的匹配条件都成立且优先级一致时,只会执行第一个匹配的模板,不会同时执行多个。你的两个模板都是针对m:project节点,分别判断是否缺少某个子节点,这种情况下无法一次性完成两个节点的插入。

修正后的XSLT代码

我们可以把两个插入逻辑合并到同一个模板里,同时检查两个节点是否存在,分别处理缺失的情况:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns="http://maven.apache.org/POM/4.0.0" 
                xmlns:m="http://maven.apache.org/POM/4.0.0" 
                exclude-result-prefixes="m">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes" />

    <!-- 基础拷贝模板:保留所有原有节点和属性 -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <!-- 统一处理project节点,一次性检查并插入缺失的两个节点 -->
    <xsl:template match="m:project">
        <project>
            <!-- 先拷贝原有的所有属性和节点 -->
            <xsl:apply-templates select="@*|node()"/>
            
            <!-- 如果不存在distributionManagement节点,插入它 -->
            <xsl:if test="not(m:distributionManagement)">
                <distributionManagement>
                    <snapshotRepository>
                        <id>xxxx.repo</id>
                        <name>xxxx Nexus snapshot repository</name>
                        <url>http://xxx/repository/maven-snapshots/</url>
                    </snapshotRepository>
                    <repository>
                        <id>xxx.repo</id>
                        <name>xxxx Nexus repository</name>
                        <url>http://xxx/repository/maven-releases/</url>
                    </repository>
                </distributionManagement>
            </xsl:if>
            
            <!-- 如果不存在profiles节点,插入它 -->
            <xsl:if test="not(m:profiles)">
                <profiles>
                    <profile>
                        <id>dev</id>
                        <properties>
                            <env>devel</env>
                            <snapshot>-SNAPSHOT</snapshot>
                        </properties>
                    </profile>
                    <profile>
                        <id>prod</id>
                        <properties>
                            <env>prod</env>
                            <snapshot></snapshot>
                        </properties>
                    </profile>
                </profiles>
            </xsl:if>
        </project>
    </xsl:template>
</xsl:stylesheet>

关键改进点

  1. 把原来的两个m:project模板合并成一个,避免模板匹配冲突
  2. 在同一个模板里,用<xsl:if>分别检查distributionManagement和profiles是否存在
  3. 先完成原有内容的拷贝,再根据缺失情况插入对应的节点,保证原有结构不受影响

这样处理后,不管你的pom里是缺少其中一个节点,还是两个都缺少,一次XSLT转换就能完成所有缺失节点的插入,不用重复执行两次。

内容的提问来源于stack exchange,提问作者zamek 42

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:08:20