来自数组响应的 Oracle 12c PLSQL SOAP EXTRACTVALUE
Oracle 12c PLSQL SOAP EXTRACTVALUE from Array response
我需要使用 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 或其他方法提取数组字段?
提前致谢!
编辑:我的肥皂包装纸 returns 这个 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不完整;假设您确实仍然拥有 SOAP 信封和主体,您可以将 XMLTable 与 XML 命名空间一起使用,如前所示(和 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)
由于示例中的换行符和前导空格,这有点混乱。如果这些真的存在,你可以 trim 关闭它们:
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 将无效并且无法正确解析,因此您需要删除命名空间前缀,或重新添加包装器。根据您之前的问题,我不不过我觉得是这样。
我需要使用 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 或其他方法提取数组字段? 提前致谢!
编辑:我的肥皂包装纸 returns 这个 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不完整;假设您确实仍然拥有 SOAP 信封和主体,您可以将 XMLTable 与 XML 命名空间一起使用,如前所示(和 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)
由于示例中的换行符和前导空格,这有点混乱。如果这些真的存在,你可以 trim 关闭它们:
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 将无效并且无法正确解析,因此您需要删除命名空间前缀,或重新添加包装器。根据您之前的问题,我不不过我觉得是这样。