提问人:Ranjeet 提问时间:9/9/2023 最后编辑:CyrusRanjeet 更新时间:9/9/2023 访问量:58
如何从soap响应中解析xpath以检索键值对
How to parse xpath from soap response to retrieve key value pair
问:
使用 bash 我试图从下面的 soap 响应中提取 id 和 name 作为键值对,并希望将此对存储在 csv 文件中。 下面的 xmllint 命令返回不需要的值,因为我无法提供过滤器。 任何人都可以帮忙。 我愿意使用 xmllint 和 xmlstarlet。
我尝试过的xmllint命令:
xmllint --xpath "//*[local-name()='getAllUserApplicationsResponse']/*[local-name()='return']/*[local-name()='name']/text()" request.xml
要提取的元素:
<ax2159:id>396112</ax2159:id>
<ax2159:name>com.example.app.name</ax2159:name>
请注意,<ns:return></ns:return>
是一个重复元素。
肥皂响应:
<ns:getAllUserApplicationsResponse
xmlns:ns="http://application.app.api.admin.abc.example.com"
xmlns:ax2179="http://logging.app.api.admin.abc.example.com/xsd"
xmlns:ax2169="http://stagingarea.app.api.admin.abc.example.com/xsd"
xmlns:ax2159="http://types.core.api.admin.abc.example.com/xsd"
xmlns:ax2171="http://permission.common.app.api.admin.abc.example.com/xsd"
xmlns:ax2161="http://application.app.api.admin.abc.example.com/xsd"
xmlns:ax2183="http://component.app.api.admin.abc.example.com/xsd"
xmlns:ax2173="http://resinstance.app.api.admin.abc.example.com/xsd"
xmlns:ax2165="http://status.app.api.admin.abc.example.com/xsd"
xmlns:ax2176="http://svars.app.api.admin.abc.example.com/xsd"
xmlns:ax2187="http://binding.app.api.admin.abc.example.com/xsd"
xmlns:ax2155="http://exception.core.api.admin.abc.example.com/xsd"
xmlns:ax2156="http://fixer.core.api.admin.abc.example.com/xsd">
<ns:return
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ax2161:ApplicationShortDesc">
<ax2159:id>396112</ax2159:id>
<ax2159:name>com.example.app.name</ax2159:name>
<ax2161:environment xsi:type="ax2159:EntityIdentifier">
<ax2159:id>6175</ax2159:id>
<ax2159:name>app_environment</ax2159:name>
</ax2161:environment>
<ax2161:folder xsi:type="ax2159:EntityIdentifier">
<ax2159:id>34148</ax2159:id>
<ax2159:name>MYAPP</ax2159:name>
</ax2161:folder>
<ax2161:runtimeState>Running</ax2161:runtimeState>
<ax2161:runtimeStateEnum>RUNNING</ax2161:runtimeStateEnum>
</ns:return>
</ns:getAllUserApplicationsResponse>
答:
1赞
pmf
9/9/2023
#1
对于此任务,您可以考虑使用 xq。它可以读取XML和写入CSV,并负责所有的引用和转义。
xq -r '."ns:getAllUserApplicationsResponse"."ns:return"
| arrays[] // . | [."ax2159:id", ."ax2159:name"] | @csv
' request.xml
"396112","com.example.app.name"
评论
0赞
Ranjeet
9/9/2023
XQ真的很棒。我有点担心,因为“ax2159”可能会随着产品版本的变化而改变。是否可以将此xml转换为json?如果我尝试放置“accept: application/json”标头,API 将返回无效的 JSON。
0赞
LMC
9/9/2023
#2
这可以通过考虑命名空间的 shell 来完成xmllint
printf "%s\n" "setrootns" 'cat //ns:return/*[name()="ax2159:id" or name()="ax2159:name"]/text()' 'bye' | xmllint --shell test.xml
原始结果
/ > setrootns
/ > cat //ns:return/*[name()="ax2159:id" or name()="ax2159:name"]/text()
-------
396112
-------
com.example.app.name
/ > bye
过滤不需要的行... | grep -vE '^\/ >| ---'
结果
396112
com.example.app.name
Xpath 也可以写成(可能更好)
//ns:return/ax2159:id/text() | //ns:return/ax2159:name/text()
评论
1赞
Léa Gris
9/9/2023
您不需要括号即可将其通过管道传递给 xmllint。它甚至适得其反,因为括号会生成一个 shell。如果确实需要通过管道传递多个命令的输出,请使用大括号,并在大括号内的每个命令后添加一个分号。但这里根本不需要:printf "%s\n" 'setrootns' 'cat //ns:return/*[name()="ax2159:id" or name()="ax2159:name"]/text()' 'bye' | xmllint --shell test.xml
评论