当前位置: 首页 > 知识库问答 >
问题:

以编程方式替换pom.xml中的依赖版本?

甄阳朔
2023-03-14

假设我有一个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>com.example</groupId>
        <artifactId>some-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
</project>

有没有一种方法可以通过编程(可能是通过脚本)替换1.0.0-SNAPSHOT版本?

我的用例:

  • 我有很多pom。需要更改父版本的xml文件

例如,我可以执行以下操作,但这将更新pom.xml中所有出现的1.0.0-SNAPSHOT,并且我希望将其限制为仅具有版本1.0.0-的一些父工件SNAPSHOT

git-xargs \
  --branch-name test-branch \
  --github-org <your-github-org> \
  --commit-message "Update pom.xml" \
  sed -i 's/1.0.0-SNAPSHOT/2.0.1/g' pom.xml

根据git xargs文档,我可以使用任何类型的脚本来处理pom。xml、bash、python、ruby等:https://github.com/gruntwork-io/git-xargs#how-提供要运行的命令或脚本

更新:

以下xmlstarlet方法在一定程度上有效:

if [[ $(xmlstarlet sel -N my=http://maven.apache.org/POM/4.0.0 -t -v '//my:project/my:parent/my:artifactId' pom.xml) == "some-parent" && $(xmlstarlet sel -N my=http://maven.apache.org/POM/4.0.0 -t -v '//my:project/my:parent/my:version' pom.xml) == "1.0.0-SNAPSHOT" ]]; then xmlstarlet edit -L -N my=http://maven.apache.org/POM/4.0.0 --update '//my:project/my:parent/my:version' --value '2.0.6' pom.xml; fi

xmlstarlet正确地更新了我想要的xml元素,但它也重新排列了文件顶部的xsi:schemaLocationxmlnsxmlns:xsi

它正在从以下位置进行更新:

<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

致:

<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">

这对我没好处。

共有3个答案

夏飞鹏
2023-03-14

你可以用xq。

只需将某个元素设置为一个新值就可以了

xq -x '.project.parent.version = "2.0.1"' pom.xml

把它设为条件是

xq -x '(.project.parent | select(
  .artifactId == "some-parent" and .version == "1.0.0-SNAPSHOT"
)).version = "2.0.1"' pom.xml

有了样本数据,两者都会产生

<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>com.example</groupId>
    <artifactId>some-parent</artifactId>
    <version>2.0.1</version>
  </parent>
</project>

如您所见,属性的顺序保持不变,但是缩进不同,尤其是您的标签内换行符被吞没了。此外,XML声明(第一行)和注释(如果存在于输入中)也不见了。也许这对你来说也不可行,但是考虑一下

  • 编辑逻辑结构(而不是文本表示)不太容易出错,
  • 所有这些问题(当然,除了缺少的注释)都可以很容易地使用许多可用于命令行的XML漂亮打印机中的一个来解决。这是一个(非详尽的)从这里去哪里的列表。

例如,让我们用tidy。

有了这个配置

xq -x '…' pom.xml |
tidy -xml -iq -utf8 --indent-with-tabs yes --indent-spaces 4 --tab-size 4 \
  --indent-attributes yes --add-xml-decl yes

你会走到最远

<?xml version="1.0"?>
<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>com.example</groupId>
        <artifactId>some-parent</artifactId>
        <version>2.0.1</version>
    </parent>
</project>

就我所见,这仍然缺少顶行声明中的encoding=“UTF-8”(tidy拒绝打印明显的声明),属性的缩进仍然减少了1个字符。如果这仍然是一个问题,试着和其他漂亮的打印机一起玩。很有可能你会找到一个完美的完成。

马浩淼
2023-03-14
匿名用户

使用xmlstarlet:

虽然您可以对xmlstarlet sel使用--if--elle(例如,请参阅https://stackoverflow.com/a/35671038/2703456),但我认为您不能对xmlstarlet ed使用它们。我几乎从不使用xmlstarlet,所以我不完全确定。
这意味着你必须在Bash中完成它...

$ if [[ $(xmlstarlet sel -t -v 'parent/version' pom.xml) == "1.0.0-SNAPSHOT" ]]
  then xmlstarlet ed -O -u 'parent/version' -v 2.0.1 pom.xml
  fi
<parent>
  <groupId>com.example</groupId>
  <artifactId>some-parent</artifactId>
  <version>2.0.1</version>
</parent>

西德尔:

$ xidel -s pom.xml -e '
  if (parent/version = "1.0.0-SNAPSHOT")
  then x:replace-nodes(parent/version/text(),"2.0.1")
  else ()
' --output-node-format=xml
<parent>
    <groupId>com.example</groupId>
    <artifactId>some-parent</artifactId>
    <version>2.0.1</version>
</parent>

如果希望输出包含XML声明,则对于xmlstarlet请删除-O选项,对于xidel请使用--output format=XML

鞠建安
2023-03-14

应该避免将xml作为纯文本文件使用,但如果没有其他选择,可以尝试一下sed范围(/starting regex/,/ending regex/{commands})允许在特定上下文中限制替换。也就是说,这一行:

sed-e'/

将只替换版本字符串

 类似资料:
  • 问题内容: 如何以编程方式在Maven执行环境之外获取Maven模块的所有依赖关系? 到目前为止,我有: 通过maven-core: 并通过jcabi-aether: 到目前为止,这通常正确吗? 现在的问题是,我得到了NullPointerException: 因为mavenProject.getRemoteProjectRepositories()返回null。 如何在考虑settings.xm

  • 问题内容: 我是Yeoman / Grunt / Bower的新手。我有一个定义以下依赖项的文件: bower.json 在我的html文件中,我使用的是这些库的非精简版本,这些版本是通过命令安装的 index.html 如何配置grunt,因此它将: 仅将这些js文件的缩小版本复制到构建目录 替换HTML所以它会如变更至 不使用CDN时-是否建议将所有文件与自定义应用程序脚本结合在一起? 这里正

  • 我有一个使用Spring的项目。它使用的是3.1.1版本,但是,由于某些原因,我真的不知道,有些spring工件与两个不同的版本是重复的。我在项目中的所有pom.xml文件中查找这些依赖项。我还使用dependecy插件来找出那些依赖项包含在哪里。 这里有输出的提取 据我所知,这意味着包含在中。 更新:似乎当我评论下一段代码时,罐子不包括在战争中。

  • 我不断得到原因:java.nio.file.nosuchfileException:C:\Program Files\Apache Software Foundation\Tomcat 9.0\WTPWebApps\WebApp\WEB-INF\lib\Jackson-DataBind-2.9.6.jar Exception。我的pom.xml文件中有2.9.6版本的依赖项,但Maven depe

  • 有什么方法可以获得手机当前运行的API版本吗?

  • 问题内容: 我知道我可以找到我正在运行的Swift版本,还原到Terminal并输入: 另外,我一直在阅读有关Swift中的预处理器宏的信息,但是找不到Swift版本常量很幸运。 随着Swift 1.2的到来,最好标记仅在Swift 1.1上运行的旧代码(Xcode最高为6.2)或需要Xcode 6.3的新代码(Swift 1.2)。 注意:我也可以使用system()做类似的事情: 然后打开so