0

我需要使用 SOAP api 并从响应中提取值。我对命名字段没有问题,但是这次响应是数组。这是示例响应:

<soap:Envelope
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
        <soap:Body>
            <getDhcpForPortResponse
                xmlns="urn:DHCPProv">
                <soapenc:Array
                    soapenc:arrayType="soapenc:Array[2]"
                    xsi:type="soapenc:Array">
                    <item
                        soapenc:arrayType="xsd:string[5]"
                        xsi:type="soapenc:Array">
                        <item
                            xsi:type="xsd:string">
                            qbtp8482tv
                            </item>
                        <item
                            xsi:type="xsd:string">
                            172.28.223.117
                            </item>
                        <item
                            xsi:type="xsd:string">
                            bc644ba2501c
                            </item>
                        <item
                            xsi:type="xsd:string">
                            MA5600T_AMD-Vitez atm 0/13/0/49:0.40
                            </item>
                        <item
                            xsi:type="xsd:string"/>
                        </item>
                    <item
                        soapenc:arrayType="xsd:string[5]"
                        xsi:type="soapenc:Array">
                        <item
                            xsi:type="xsd:string">
                            qbtp8482tv
                            </item>
                        <item
                            xsi:type="xsd:string">
                            172.28.223.126
                            </item>
                        <item
                            xsi:type="xsd:string">
                            704fb8f3e4e1
                            </item>
                        <item
                            xsi:type="xsd:string">
                            MA5600T_AMD-Vitez atm 0/13/0/49:0.40
                            </item>
                        <item
                            xsi:type="xsd:string"/>
                        </item>
                    </soapenc:Array>
                </getDhcpForPortResponse>
            </soap:Body>
        </soap:Envelope>

有没有办法用 EXTRACTVALUE 或其他方法提取数组字段?提前致谢!

编辑:我的肥皂包装返回这个 xml:

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getDhcpForUsernameResponse xmlns="urn:DHCPProv">
      <soapenc:Array soapenc:arrayType="soapenc:Array[2]" xsi:type="soapenc:Array">
        <item soapenc:arrayType="xsd:string[5]" xsi:type="soapenc:Array">
          <item xsi:type="xsd:string">qbtp8482tv</item>
          <item xsi:type="xsd:string">172.28.223.117</item>
          <item xsi:type="xsd:string">bc644ba2501c</item>
          <item xsi:type="xsd:string">MA5600T_AMD-Vitez atm 0/13/0/49:0.40</item>
          <item xsi:type="xsd:string"/>
        </item>
        <item soapenc:arrayType="xsd:string[5]" xsi:type="soapenc:Array">
          <item xsi:type="xsd:string">qbtp8482tv</item>
          <item xsi:type="xsd:string">172.28.223.126</item>
          <item xsi:type="xsd:string">704fb8f3e4e1</item>
          <item xsi:type="xsd:string">MA5600T_AMD-Vitez atm 0/13/0/49:0.40</item>
          <item xsi:type="xsd:string"/>
        </item>
      </soapenc:Array>
    </getDhcpForUsernameResponse>
  </soap:Body>
</soap:Envelope>

但是当我在 select 语句中使用该 xml 时,它不会从中获取任何值。与我发布的从wireshark复制的第一个相比有什么区别?

4

1 回答 1

0

您的 XML 不完整;假设您确实仍然有 SOAP 信封和正文,您可以将 XMLTable 与 XMLNamespaces 一起使用,如前所示(并且extractvalue仍然不推荐使用):

select item
from XMLTable(
  XMLNamespaces (
    default 'urn:DHCPProv',
    'http://schemas.xmlsoap.org/soap/envelope/' as "soap",
    'http://schemas.xmlsoap.org/soap/encoding/' as "soapenc"
  ),
  '/soap:Envelope/soap:Body/getDhcpForPortResponse/soapenc:Array/item/item'
  passing XMLType(xml_string)
  columns item varchar2(4000) path '.'
)

因此,使用您的数据和添加的 SOAP 位:

select item
from XMLTable(
  XMLNamespaces (
    default 'urn:DHCPProv',
    'http://schemas.xmlsoap.org/soap/envelope/' as "soap",
    'http://schemas.xmlsoap.org/soap/encoding/' as "soapenc"
  ),
  '/soap:Envelope/soap:Body/getDhcpForPortResponse/soapenc:Array/item/item'
  passing XMLType('<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
            <getDhcpForPortResponse
                xmlns="urn:DHCPProv">
                <soapenc:Array
                    soapenc:arrayType="soapenc:Array[2]"
                    xsi:type="soapenc:Array">
                    <item
                        soapenc:arrayType="xsd:string[5]"
                        xsi:type="soapenc:Array">
                        <item
                            xsi:type="xsd:string">
                            qbtp8482tv
                            </item>
                        <item
                            xsi:type="xsd:string">
                            111.11.111.111
                            </item>
                        <item
                            xsi:type="xsd:string">
                            bc644ba2501c
                            </item>
                        <item
                            xsi:type="xsd:string">
                            MF5601T_AMD-NDF
                            </item>
                        <item
                            xsi:type="xsd:string"/>
                        </item>
                    <item
                        soapenc:arrayType="xsd:string[5]"
                        xsi:type="soapenc:Array">
                        <item
                            xsi:type="xsd:string">
                            qbtp8482tv
                            </item>
                        <item
                            xsi:type="xsd:string">
                            222.22.222.222
                            </item>
                        <item
                            xsi:type="xsd:string">
                            704fb8f3e4e1
                            </item>
                        <item
                            xsi:type="xsd:string">
                            MF5601T_AMD-NDF
                            </item>
                        <item
                            xsi:type="xsd:string"/>
                        </item>
                    </soapenc:Array>
                </getDhcpForPortResponse>
 </soap:Body>
 </soap:Envelope>')
  columns item varchar2(4000) path '.'
)

得到:

ITEM
--------------------------------------------------

                            qbtp8482tv
                            

                            111.11.111.111
                            

                            bc644ba2501c
                            

                            MF5601T_AMD-NDF
                            
(null)

                            qbtp8482tv
                            

                            222.22.222.222
                            

                            704fb8f3e4e1
                            

                            MF5601T_AMD-NDF
                            
(null)

db<>小提琴

由于示例中的换行符和前导空格,这有点混乱。如果这些确实存在,您可以将它们修剪掉:

select rtrim(ltrim(item, chr(32)||chr(10)), chr(10)||chr(32)) as item
from XMLTable...

这使:

ITEM
--------------------
qbtp8482tv
111.11.111.111
bc644ba2501c
MF5601T_AMD-NDF
(null)
qbtp8482tv
222.22.222.222
704fb8f3e4e1
MF5601T_AMD-NDF
(null)

如果您不想要空值,您可以排除这些值。

如果您没有 SOAP 包装器,那就更复杂了;您可以在 XPath 中使用通配符,但 XML 将无效并且无法正确解析,因此您需要删除命名空间前缀,或重新添加包装器。根据您之前的问题,我认为这不是情况虽然。

于 2021-05-25T11:15:30.233 回答