我想在Maven项目中修改我的pom.xml。我想插入两个不存在的节点(distributionManagement和配置文件)。当我启动此xslt时,它仅插入仅distributionManagement节点,而当我再次运行它时,它将插入配置文件节点。
这是我的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>
<xsl:template match="m:project[not(m:profiles)]">
<project>
<xsl:apply-templates select="@*|node()"/>
<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>
</project>
</xsl:template>
<xsl:template match="m:project[not(m:distributionManagement)]">
<project>
<xsl:apply-templates select="@*|node()"/>
<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>
</project>
</xsl:template>
这是pom.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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>TestApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
答案 0 :(得分:2)
我建议将新值的代码移至参数,然后,至少在XSLT 1中,我认为您可以简单地在模板中检查project
,其中两个xsl:if
用于您要寻找的两个孩子,如果不存在,请添加它们:
<xsl:template match="m:project[not(m:profiles) or not(m:distributionManagement)]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:if test="not(m:profiles)">
<xsl:copy-of select="$new-profiles"/>
</xsl:if>
<xsl:if test="not(m:distributionManagement)">
<xsl:copy-of select="$new-dist-man"/>
</xsl:if>
</xsl:copy>
</xsl:template>
完整代码
<xsl:stylesheet 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"
version="1.0">
<xsl:output indent="yes"/>
<xsl:param name="new-dist-man">
<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:param>
<xsl:param name="new-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:param>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="m:project[not(m:profiles) or not(m:distributionManagement)]">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:if test="not(m:profiles)">
<xsl:copy-of select="$new-profiles"/>
</xsl:if>
<xsl:if test="not(m:distributionManagement)">
<xsl:copy-of select="$new-dist-man"/>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用XSLT 3(可能在Java中使用Maven或Sourceforge的Saxon 9.8或9.9 HE的Java),由于参数是常规序列,因此它变得更加紧凑,我们可以简单地在谓词中测试上下文节点是否没有适当的子代:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://maven.apache.org/POM/4.0.0"
xpath-default-namespace="http://maven.apache.org/POM/4.0.0"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output indent="yes"/>
<xsl:param name="new-dist-man">
<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:param>
<xsl:param name="new-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:param>
<xsl:template match="project[not(profiles) or not(distributionManagement)]">
<xsl:copy>
<xsl:apply-templates select="@*, node(), $new-profiles[not(current()/profiles)], $new-dist-man[not(current()/distributionManagement)]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>