使用Oracle SQL读取XML命名空间

时间:2018-09-04 06:01:40

标签: sql oracle xml-namespaces xmltype xmltable

我的XML如下所示

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>  
<wfm:Statement xmlns:wfm="http://example.org/sample/xsd/sampleStatement/2013/05" xmlns:wfmMerchant="http://www.eds.com/sample/xsd/wfmMerchant/2012/03"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  
  <wfm:StatementParameters>  
    <wfmMerchant:HierarchyCd>012-12-002-107-050</wfmMerchant:HierarchyCd>   
  </wfm:StatementParameters>  
  <StatementAmount>27.140</StatementAmount>  
</wfm:Statement>

我正尝试使用如下所示的Oracle查询来获取StatementAmount标签的值

select MS.MERCHANT,MS.CHAIN_HIERARCHY_CD,MS.CYCLE_DATE, X.StatementAmount
FROM CHAIN_STATMNT_HIST_XML MS  
CROSS JOIN XMLTABLE(XMLNAMESPACES('http://example.org/sample/xsd/sampleStatement/2013/05' AS "wfm", 'http://www.eds.com/sample/xsd/wfmMerchant/2012/03' as wfmmerchant
     default 'http://www.w3.org/2001/XMLSchema-instance')
     ,'/wfm:Statement/StatementAmount' passing xmltype(MS.XML_REPORT) 
     columns StatementAmount varchar(18) path '.')X

但是,我总是得到NULL。我可以从具有名称空间的XML中成功检索层次结构值。但是StatementAmount标记没有任何名称空间,我在检索它时遇到了麻烦。

有人可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您的默认名称空间声明似乎引起了问题;否则(并忽略wfmMerchant):

-- CTE for sample data
with CHAIN_STATMNT_HIST_XML (merchant, chain_hierarchy_cd, cycle_date, XML_REPORT) as (
  select 1, 2, sysdate, '<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<wfm:Statement xmlns:wfm="http://example.org/sample/xsd/sampleStatement/2013/05" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<wfm:StatementParameters>
<!-- excluding this as namespace not provided -->
<!-- <wfmMerchant:HierarchyCd>012-12-002-107-050</wfmMerchant:HierarchyCd> -->
</wfm:StatementParameters>
<StatementAmount>27.140</StatementAmount>
</wfm:Statement>' from dual
)
-- actual query
select MS.MERCHANT,MS.CHAIN_HIERARCHY_CD,MS.CYCLE_DATE, X.StatementAmount
FROM CHAIN_STATMNT_HIST_XML MS  
CROSS JOIN XMLTABLE(
  XMLNAMESPACES('http://example.org/sample/xsd/sampleStatement/2013/05' AS "wfm"),
  '/wfm:Statement/StatementAmount' passing xmltype(MS.XML_REPORT)
  columns StatementAmount varchar(18) path '.'
) X
/

  MERCHANT CHAIN_HIERARCHY_CD CYCLE_DATE STATEMENTAMOUNT   
---------- ------------------ ---------- ------------------
         1                  2 2018-09-04 27.140            

我不确定您为什么将varchar2(18)用作数据类型而不是number;并且如果每个语句只有一个语句量,您可以执行以下操作:

select MS.MERCHANT,MS.CHAIN_HIERARCHY_CD,MS.CYCLE_DATE, X.StatementAmount
FROM CHAIN_STATMNT_HIST_XML MS  
CROSS JOIN XMLTABLE(
  XMLNAMESPACES('http://example.org/sample/xsd/sampleStatement/2013/05' AS "wfm"),
  '/wfm:Statement' passing xmltype(MS.XML_REPORT)
  columns StatementAmount number path 'StatementAmount'
) X