我有一个典型的 pom.xml,想打印 groupId、artifactId 和 version,用冒号分隔。我认为XMLStarlet是正确的工具。我尝试了几种方法,但我总是得到一个空行。
xml sel -t -m project -v groupId -o : -v artifactId -o : -v version pom.xml
预期输出:
org.something.apps:app-acct:5.4
实际输出:空行
即使我尝试只打印 groupId,我也一无所获:
xml sel -t -v project/groupId pom.xml
我确信该工具可以看到这些元素,因为我可以毫无问题地列出它们:
xml el pom.xml
打印以下(正确):
project
project/modelVersion
project/parent
project/parent/groupId
project/parent/artifactId
project/parent/version
project/groupId
project/artifactId
project/version
project/packaging
怎么了?
这是 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.something</groupId>
<artifactId>base</artifactId>
<version>1.16</version>
</parent>
<groupId>org.something.apps</groupId>
<artifactId>app-acct</artifactId>
<version>5.4</version>
<packaging>war</packaging>
</project>
最佳答案
不幸的是,XMLStarlet 对默认 namespace 非常挑剔。如果文档已经声明了它( xmlns=
),您也必须为 XMLStarlet 声明它,并用您选择的名称作为元素的前缀(参见 here ):
xml sel -N my=http://maven.apache.org/POM/4.0.0 -t -m my:project -v my:groupId -o : -v my:artifactId -o : -v my:version pom.xml
运行上面的命令会得到预期的输出:
org.something.apps:app-acct:5.4
但是,如果文档没有声明默认命名空间(或者命名空间的 URL 略有不同),则上述命令将不起作用,这是一个真正的 PITA。更通用的解决方案是在选择元素之前删除默认命名空间声明。从 XMLStarlet 1.3.1 开始,将 XML 转换为 PYX 格式并返回会删除命名空间声明:
xml pyx pom.xml | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version 2>nul
更新 (2014-02-12): 从 XMLStarlet 1.4.2 开始,PYX <-> XML 转换是固定的(不删除命名空间声明),因此上述命令将不起作用(感谢 Peter Gluck 的提示)。请改用以下命令:
xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version
注意:上面的 grep 从文档中删除了所有属性,而不仅仅是命名空间声明。对于这种特定情况(从 pom.xml 中选择元素值,其中不需要具有非默认命名空间的元素)是可以的,但是对于一般的 XML,您将只删除默认命名空间声明而不是其他任何内容:
xml pyx pom.xml | grep -v "^Axmlns " | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version
注意(已过时):错误重定向(
2>nul
)对于隐藏对(现在)未知命名空间 xsi 的提示是必要的:-:1.28: Namespace prefix xsi for schemaLocation on project is not defined
摆脱提示的另一种方法是删除 schemaLocation 属性(实际上,此命令从 PYX 文档中删除了所有属性,而不仅仅是 xsi:schemaLocation):
xml pyx pom.xml | grep -v ^A | xml p2x | xml sel -t -m project -v groupId -o : -v artifactId -o : -v version
关于command-line-interface - XMLStarlet 不选择任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9025492/