Native shell命令设置为从XML提取节点值

Kar*_*. V 27 xml xmllint

我正在尝试从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>
Run Code Online (Sandbox Code Playgroud)

我需要使用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(没有输出).

我在这里意识到这是一个常见问题,但上述几点是我不能使用这些答案的原因.TIA的帮助.

Sal*_*lem 19

--format仅用于格式化(缩进等)文档.您可以使用--xpath(在Ubuntu中测试,libxml v20900):

$ xmllint --xpath "//project/parent/version/text()" pom.xml
1.5.0
Run Code Online (Sandbox Code Playgroud)

  • 另外:`xpath -q -e"// project/parent/version/text()"pom.xml` (3认同)

Kar*_*. V 15

I've managed to solve it for the time being with this rather unwiedly script using xmllint --shell.

echo "cat //project/parent/version" | xmllint --shell pom.xml | sed '/^\/ >/d' | sed 's/<[^>]*.//g'
Run Code Online (Sandbox Code Playgroud)

If the XML nodes have namespace attributes like my pom.xml had, things get heavier, basically extracting the node by name:

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

Hope it helps. If anyone can simply these expressions, I'd be grateful.

  • 或者,您可以使用:`echo"cat //*[local-name()='project']/*[local-name()='parent']/*[local-name()='version' ]/text()"| xmllint --shell pom.xml | sed'/ ^\/>/d'`,所以你只需要`sed`-删除xmllint shell的东西 (2认同)

lys*_*xia 5

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

我需要提取elasticsearch .deb文件的最新稳定版本并安装它.维护者已经将版本号放在带有"版本"类的范围内.

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

怎么回事:

我们使用curl -s(silent)选项.

curl -s http://www.elasticsearch.org/download/
Run Code Online (Sandbox Code Playgroud)

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

'//span[@class="version"]/text()'
Run Code Online (Sandbox Code Playgroud)

...查找具有class属性(@class)"version"的<span>节点,并提取文本值(/ text()).

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

 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

最后,请注意xmllint命令末尾的" - ",它告诉xmllint流来自stdin.

  • KARTHIK.V,这对你来说不是一个好的答案,但你的问题是有名的,所以它在谷歌搜索中相当高.我想我会为像我这样寻找快速答案并拥有不同工具的人添加这个. (3认同)