使用 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
我正在尝试解析 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