How to parse xpath from soap response to retrieve key value pair

76 Views Asked by At

Using bash I am trying to extract id and name as key value pair from below soap response and want to store this pair in csv file. Below xmllint command is returning unwanted values as I am not able to provide the filter. Can anyone please help. I am open to use xmllint and xmlstarlet.

xmllint command that I tried:

xmllint --xpath "//*[local-name()='getAllUserApplicationsResponse']/*[local-name()='return']/*[local-name()='name']/text()" request.xml

Elements to be extracted:

    <ax2159:id>396112</ax2159:id>
    <ax2159:name>com.example.app.name</ax2159:name>

Please note that <ns:return></ns:return> is a repeating element.

Soap Response:

<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>
2

There are 2 best solutions below

2
pmf On BEST ANSWER

For this task, you could consider using xq. It can read XML and write CSV, and takes care of all the quoting and escaping.

xq -r '."ns:getAllUserApplicationsResponse"."ns:return"
  | arrays[] // . | [."ax2159:id", ."ax2159:name"] | @csv
' request.xml
"396112","com.example.app.name"
1
LMC On

It can be done with xmllint shell taking namespaces into consideration

printf "%s\n" "setrootns" 'cat //ns:return/*[name()="ax2159:id" or name()="ax2159:name"]/text()' 'bye' | xmllint --shell test.xml 

Raw result

/ > setrootns
/ > cat //ns:return/*[name()="ax2159:id" or name()="ax2159:name"]/text()
 -------
396112
 -------
com.example.app.name
/ > bye

Filtering unwanted lines with ... | grep -vE '^\/ >| ---'

Result

396112
com.example.app.name

Xpath can be written also as (probably better)

//ns:return/ax2159:id/text() | //ns:return/ax2159:name/text()