【问题标题】:Oracle 12c PLSQL SOAP EXTRACTVALUE from Array response来自数组响应的 Oracle 12c PLSQL SOAP EXTRACTVALUE
【发布时间】:2021-08-13 13:45:30
【问题描述】:

我需要使用 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复制的第一个相比有什么区别?

【问题讨论】:

  • 这是你的整个 XML 还是你有一个围绕它的元素来定义命名空间?
  • 我编辑了我的帖子并添加了完整的 xml 信封。

标签: xml oracle soap extract-value


【解决方案1】:

您的 XML 不完整;假设你真的还有 SOAP 信封和正文,你可以使用 XMLTable 和 XMLNamespaces,如前所示(和extractvalue is still deprecated):

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

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

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 将无效并且无法正确解析,因此您需要删除命名空间前缀,或重新添加包装器。根据您之前的问题,我认为这不是不过情况。

【讨论】:

  • 抱歉,我编辑了我的帖子并添加了完整的 xml 信封。
  • @BorisMamić - 我认为这正是我在示例中所假设的;取自您之前的问题。
  • @BorisMamić - 检查什么?答案仍然适用。你只是不再需要修剪它。 The query still works - 只要 XPath 更改以匹配文档(即使用 /getDhcpForUsernameResponse/ 而不是 /getDhcpForPortResponse/)。如果您的某些问题仍然无法正常工作,请提出一个包含所有相关信息的新问题,包括您遇到的任何问题。
猜你喜欢
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
相关资源
最近更新 更多