使用 xmllint 解析 xml 格式的 curl 响应

Parsing curl response in xml format with xmllint

我正在尝试解析 xml 格式的 curl 响应以检索 'version' 的值。我正在使用以下命令:

curl -v -k -X GET -u username:password -H "Content-Type: application/xml" -H "Accept: application/xml" http://dev_server_host:8080/rest/process/list/template?process=notification_process | xmllint  --xpath "//proc:version" -

PFB,当我不使用 xmllint 时此 curl 命令的示例响应。

<proc:basicProcessTemplate  xmlns:proc="http://www.example.com/bx/2009/management/processManagerType">
    <proc:processQName>
        <proc:moduleName>some_awesome_notification_module</proc:moduleName>
        <proc:processName>notification_process</proc:processName>
        <proc:version>1.0.0.20220215185833172</proc:version>
    </proc:processQName>
    <proc:description>sample process to send notifications</proc:description>
</proc:basicProcessTemplate>

但是,当我如上所述使用 xmllint 时,终端中显示以下错误:

XPath error : Undefined namespace prefix
xmlXPathEval: evaluation failed
XPath evaluation failure

能否请您帮助确定正确的 xpath,我可以在 xmllint 命令中发送它来检索 'version'.

的值

请注意:由于我使用查询参数 'process',因此只会返回一个 'proc:processQName' 元素作为响应。 'proc:processQName' 元素的响应中不需要数组。

命名空间已被使用但未在您要查找的节点中定义。

因此您必须修改查询以分别检查节点的名称和命名空间:

xmllint --xpath '//*[
  namespace-uri() = "http://www.example.com/bx/2009/management/processManagerType"
  and local-name() = "version"
]/text()'
1.0.0.20220215185833172

如果名称空间是在父节点中定义的(如您的根节点中的情况),您可以通过引用检查来简化查询:

xmllint --xpath '//*[
  namespace-uri() = namespace-uri(/*) and local-name() = "version"
]/text()'
1.0.0.20220215185833172

如果您的查询不依赖于特定的命名空间,您也可以完全省略该部分和 select 具有任何命名空间的节点(尽管与名称匹配):

xmllint --xpath '//*[local-name() = "version"]/text()'
1.0.0.20220215185833172

您可能也有兴趣使用另一个不那么迂腐的工具:

使用 XMLStarlet 您基本上可以使用原始查询字符串:

xmlstarlet sel -t -v "//proc:version"
1.0.0.20220215185833172

xq, querying is a little bit different because under the hood it is actually running a jq查询:

xq -r '.. | ."proc:version"? // empty'
1.0.0.20220215185833172