XMLTable 查询 returns 无结果
XMLTable query returns no result
我对 XML 只是略微熟悉。我需要解析来自 SOAP 请求的响应。通过大量搜索,我开发了以下查询来尝试提取状态。最后,我想从响应中获取状态、cntr 和 cntr_status 字段。我的查询没有给出错误,但也没有结果。我犯了什么菜鸟错误?
SELECT *
FROM XMLTABLE (
XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
'http://service.xxx.com/' AS "xxx"),
'/soapenv:Envelope/soapenv:Body/xxx:sendDataResponse/xxx:sendDataReturn/xxx:result'
PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' <cntr_result>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>')
COLUMNS status VARCHAR2(20) PATH 'xxx:status') xmlstuff ;
来自服务的示例响应被硬编码到 XMLTYPE 函数中。
我已经尝试了任意数量的涉及 xxx 命名空间的查询字符串和列路径,都没有产生任何结果。
可能有数百个 cntr 和 cntr_status 对。
感谢观看!
使用 DEFAULT
命名空间(因为您没有为 http://service.xxx.com
定义前缀)并删除对 xxx:
的引用似乎有效:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
sqlfiddle here
然后得到第一个cntr
和cntr_status
:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr[1]',
cntr_status VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr_status[1]'
) xmlstuff;
sqlfiddle here
更新 XML 格式
理想情况下,您应该能够在 XMLTABLE
中使用 XPATH '/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_status/cntr_result'
,然后使用路径 ./../../status
获取 status
;但是,在尝试遍历父元素时我一直得到 null
值,但找不到有效的解决方案。
SELECT x.*
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_statuses/cntr_result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH './../../status',
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) x;
sqlfiddle here
根据 ,它将在 Oracle 11.2.0.4 中运行,但如果您在 Oracle 11.2.0.2 中尝试,则 status
将是 NULL
(这是看到的结果在 SQLFiddle 上)。
相反,对于多个 cntr_result
元素,您可以使用两个 XMLTABLE
:
SELECT x.status,
c.cntr,
c.cntr_status
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr_statuses XMLTYPE PATH 'cntr_statuses'
) x
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/cntr_statuses/cntr_result'
PASSING x.cntr_statuses
COLUMNS
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) c;
假设您的数据在 table_name
table 的 xml
列中。
则输出为:
STATUS
CNTR
CNTR_STATUS
SUCCESS
1234567890A
SUCCESS
SUCCESS
1234567890B
SUCCESS
sqlfiddle here
我对 XML 只是略微熟悉。我需要解析来自 SOAP 请求的响应。通过大量搜索,我开发了以下查询来尝试提取状态。最后,我想从响应中获取状态、cntr 和 cntr_status 字段。我的查询没有给出错误,但也没有结果。我犯了什么菜鸟错误?
SELECT *
FROM XMLTABLE (
XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
'http://service.xxx.com/' AS "xxx"),
'/soapenv:Envelope/soapenv:Body/xxx:sendDataResponse/xxx:sendDataReturn/xxx:result'
PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' <cntr_result>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>')
COLUMNS status VARCHAR2(20) PATH 'xxx:status') xmlstuff ;
来自服务的示例响应被硬编码到 XMLTYPE 函数中。
我已经尝试了任意数量的涉及 xxx 命名空间的查询字符串和列路径,都没有产生任何结果。
可能有数百个 cntr 和 cntr_status 对。
感谢观看!
使用 DEFAULT
命名空间(因为您没有为 http://service.xxx.com
定义前缀)并删除对 xxx:
的引用似乎有效:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
sqlfiddle here
然后得到第一个cntr
和cntr_status
:
SELECT *
FROM XMLTABLE (
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(
'<?xml version="1.0" encoding="UTF-8"?>' ||
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ' ||
' xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' ||
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' ||
' <soapenv:Body>' ||
' <sendDataResponse xmlns="http://service.xxx.com">' ||
' <sendDataReturn>' ||
' <result>' ||
' <build>Build 1</build>' ||
' <status>SUCCESS</status>' ||
' <cntr_statuses>' ||
' <cntr_result>' ||
' <cntr>1234567890A</cntr><cntr_status>SUCCESS</cntr_status>' ||
' <cntr>1234567890B</cntr><cntr_status>SUCCESS</cntr_status>' ||
' </cntr_result>' ||
' </cntr_statuses>' ||
' </result>' ||
' </sendDataReturn>' ||
' </sendDataResponse>' ||
' </soapenv:Body>' ||
'</soapenv:Envelope>'
)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr[1]',
cntr_status VARCHAR2(20) PATH 'cntr_statuses/cntr_result/cntr_status[1]'
) xmlstuff;
sqlfiddle here
更新 XML 格式
理想情况下,您应该能够在 XMLTABLE
中使用 XPATH '/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_status/cntr_result'
,然后使用路径 ./../../status
获取 status
;但是,在尝试遍历父元素时我一直得到 null
值,但找不到有效的解决方案。
SELECT x.*
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result/cntr_statuses/cntr_result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH './../../status',
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) x;
sqlfiddle here
根据 status
将是 NULL
(这是看到的结果在 SQLFiddle 上)。
相反,对于多个 cntr_result
元素,您可以使用两个 XMLTABLE
:
SELECT x.status,
c.cntr,
c.cntr_status
FROM table_name t
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/soapenv:Envelope/soapenv:Body/sendDataResponse/sendDataReturn/result'
PASSING XMLTYPE(t.xml)
COLUMNS
status VARCHAR2(20) PATH 'status',
cntr_statuses XMLTYPE PATH 'cntr_statuses'
) x
CROSS JOIN
XMLTABLE(
XMLNAMESPACES(
'http://schemas.xmlsoap.org/soap/envelope/' as "soapenv",
'http://www.w3.org/2001/XMLSchema' as "xsd",
'http://www.w3.org/2001/XMLSchema-instance' as "xsi",
DEFAULT 'http://service.xxx.com'
),
'/cntr_statuses/cntr_result'
PASSING x.cntr_statuses
COLUMNS
cntr VARCHAR2(20) PATH 'cntr',
cntr_status VARCHAR2(20) PATH 'cntr_status'
) c;
假设您的数据在 table_name
table 的 xml
列中。
则输出为:
STATUS CNTR CNTR_STATUS SUCCESS 1234567890A SUCCESS SUCCESS 1234567890B SUCCESS
sqlfiddle here