SOAP XML 从 shell 解析

SOAP XML parsing from shell

我需要从大型 xml 文件中获取某些数据(2018 年 doh),它是 CMDBuild SOAP API 请求的输出(旧版本,不支持 REST)。我更喜欢使用 shell 工具,例如 xmlstarlet 或 xmllint。这里是 XML:

<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <ns2:getCardListResponse
        xmlns:ns2="http://soap.services.cmdbuild.org">
        <ns2:return>
            <ns2:cards>
                <ns2:attributeList>
                    <ns2:name>instance_id</ns2:name>
                    <ns2:value>5919</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Description</ns2:name>
                    <ns2:value>CentOS-7-x86-64-1708</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>instance_name</ns2:name>
                    <ns2:value>i-2-5919-VM</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>hypervisor_hostname</ns2:name>
                    <ns2:value>ct-hn-v-4754875487</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>private_mac_address</ns2:name>
                    <ns2:value>1e:00:0f:00:04:97</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>base_hostname</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>cloudstack_name</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>private_ip_address</ns2:name>
                    <ns2:value>10.0.215.48</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Code</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>uuid</ns2:name>
                    <ns2:value>d54d08d0-83ef-47bb-b4aa-f0b2c8105639</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Notes</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:beginDate>2018-01-24T12:00:00.031+02:00</ns2:beginDate>
                <ns2:className>cloudstack</ns2:className>
                <ns2:id>1540303</ns2:id>
            </ns2:cards>
            <ns2:cards>
                <ns2:attributeList>
                    <ns2:name>instance_id</ns2:name>
                    <ns2:value>7259</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Description</ns2:name>
                    <ns2:value>CSCM-WLP-INTL-20GB</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>instance_name</ns2:name>
                    <ns2:value>i-92-7259-VM</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>hypervisor_hostname</ns2:name>
                    <ns2:value>ct-hn-v-85847487584</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>private_mac_address</ns2:name>
                    <ns2:value>1e:00:1e:00:04:7a</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>base_hostname</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>cloudstack_name</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>private_ip_address</ns2:name>
                    <ns2:value>10.0.215.19</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Code</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>uuid</ns2:name>
                    <ns2:value>eab5f52b-7225-4c51-9ca7-f26757a0d7f5</ns2:value>
                </ns2:attributeList>
                <ns2:attributeList>
                    <ns2:name>Notes</ns2:name>
                    <ns2:value></ns2:value>
                </ns2:attributeList>
                <ns2:beginDate>2018-01-24T16:15:00.018+02:00</ns2:beginDate>
                <ns2:className>cloudstack</ns2:className>
                <ns2:id>1542507</ns2:id>
            </ns2:cards>
            <ns2:totalRows>29</ns2:totalRows>
        </ns2:return>
    </ns2:getCardListResponse>
</soap:Body>

没什么要补充的,我怎样才能得到所有 instane_name 字段的值,或者 private_ip_address?

Br, 伊戈尔.

xmlstarlet 解法:

-- 至 select 所有“instance_name”节点值:

xmlstarlet sel -N soap="http://schemas.xmlsoap.org/soap/envelope/" \
-N ns2="http://soap.services.cmdbuild.org" --net \
-t -v "//ns2:attributeList/ns2:name[.='instance_name']/following-sibling::ns2:value" \
-n input.xml

输出:

i-2-5919-VM
i-92-7259-VM

-- 至 select 所有“private_ip_address”节点值:

xmlstarlet sel -N soap="http://schemas.xmlsoap.org/soap/envelope/" \
-N ns2="http://soap.services.cmdbuild.org" --net \
-t -v "//ns2:attributeList/ns2:name[.='private_ip_address']/following-sibling::ns2:value" \
-n input.xml

输出:

10.0.215.48
10.0.215.19