28

我正在尝试从 pom.xml 中提取节点的值:

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <parent>
        <groupId>org.me.labs</groupId>
        <artifactId>my-random-project</artifactId>
        <version>1.5.0</version>
    </parent>
    ...
</project>

我需要使用 shell 命令从 XML 中提取 artifactId 和版本。我有以下要求/意见:

  1. shell 脚本将在我们在工作中使用的构建程序集文件中完成,因此脚本越小越好。
  2. 由于它将在多个系统(通常是 RHEL5)上使用,我正在寻找可以在默认图像上本机运行的东西。
  3. 像这样的标签可以出现在 pom 的其他地方,所以我不能简单地为这些标签 awk。

我尝试了以下方法:

  1. xpath在我的 Mac 上工作,但在 RHEL 机器上默认不可用。同样对于xmllint --xpath,我猜它仅适用于更高版本的xmllint,我没有也无法强制执行。
  2. xmllint --pattern似乎很有希望,但我似乎无法从xmllint --pattern '//project/parent/version' pom.xml(打印整个 XML)或xmllint --stream --pattern '//project/parent/version' pom.xml(无输出)中获得输出。

我意识到这是 SO 上的一个常见问题,但以上几点是我不能使用这些答案的原因。TIA 为您提供帮助。

4

6 回答 6

25

--format仅用于格式化(缩进等)文档。您可以使用--xpath(在 Ubuntu 中测试,libxml v20900)来做到这一点:

$ xmllint --xpath "//project/parent/version/text()" pom.xml
1.5.0
于 2013-06-06T10:53:11.833 回答
17

我已经设法使用这个相当笨拙的脚本暂时解决了这个问题xmllint --shell

echo "cat //project/parent/version" | xmllint --shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'

如果 XML 节点具有像我的 pom.xml 那样的命名空间属性,事情会变得更重,基本上是按名称提取节点:

echo "cat //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" | xmllint --shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'

希望能帮助到你。如果有人可以简单地表达这些表达方式,我将不胜感激。

于 2013-06-06T12:34:01.397 回答
6

我来这里是为了寻找一种从网站上获取价值的好方法。以下示例可能对那些拥有支持 --xpath 的 xmllint 版本的人(与海报不同)有用。

我需要提取最新的稳定版本的 elasticsearch .debfile 并安装它。维护人员已帮助将版本号与“版本”类放在一起。

version=`curl -s http://www.elasticsearch.org/download/ |\
 xmllint --html --xpath '//span[@class="version"]/text()'\
 2>/dev/null - `;

怎么回事:

我们使用 curl -s(静默)选项。

curl -s http://www.elasticsearch.org/download/

我们使用 xmllint --html 和 --xpath 开关。xpath 参数(单引号)

'//span[@class="version"]/text()'

... 查找具有类属性 (@class) “版本”的 <span> 节点,并提取文本值 (/text())。

由于 xmllint 是(惊喜!)一个 linter,它会在你的 html 流中对不可避免的垃圾发牢骚。我们以通常的方式将 stderr 指向 /dev/null:

 2>/dev/null

最后,注意 xmllint 命令末尾的“-”,它告诉 xmllint 流来自标准输入。

于 2013-12-05T16:36:46.050 回答
3

使用text()XPath 函数可以为您提供元素值,而不必删除 XML 标记:

echo "cat //project/parent/version/text()" | xmllint --shell pom.xml
于 2013-11-06T00:36:11.430 回答
0

你可以试试

xmllint --xpath "/*[name()='project']/*[name()='groupId']/text()" pom.xml

于 2017-10-17T14:52:29.433 回答
0

使用 POM,您可能会出现名称空间问题,从而阻止xmllint按预期工作。本文为您指出了一个替代且非常好的解决方案(查看sed段落)。

于 2018-04-23T06:19:47.027 回答