从 XML 文件中提取值

Extract Value from XML file

我正在尝试从 XML 文件中获取值,如下所示。我要提取值:289

<operationExecutionResponse>
  <responseCode>0</responseCode>
  <rootContext>
    <stringList name="productIds">
      <string>289</string>
      <string>123</string>
    </stringList>
  </rootContext>
</operationExecutionResponse>

我试过这样的事情:

SELECT EXTRACTVALUE (
r_val,
'//operationExecutionResponse/rootContex/stringList/string[1]')
INTO n_id
FROM DUAL;
SELECT EXTRACTVALUE (
r_val,
'//operationExecutionResponse/rootContex/stringList/string[@name="productIds"]/text()')
INTO n_id
FROM DUAL;

如何获得我想要的值?

试试这个:

WITH XML_TBL 
AS  (SELECT XMLTYPE('<operationExecutionResponse>
                      <responseCode>0</responseCode>
                      <rootContext>
                        <stringList name="productIds">
                          <string>289</string>
                          <string>123</string>
                        </stringList>
                      </rootContext>
                    </operationExecutionResponse>') XMLDATA
       FROM DUAL)
SELECT VALS
  FROM XML_TBL
     , XMLTABLE(
                  'operationExecutionResponse/rootContext/stringList//*'
                  PASSING XML_TBL.XMLDATA 
                  COLUMNS VALS VARCHAR2(100) PATH 'text()'
                );

您的第一次尝试几乎是正确的,但您拼写 rootContext 错误 - 缺少最后一个 t。更正后就可以了。 (你的第二个在错误的节点上有属性名称过滤器,并且会尝试 return 所有值而不仅仅是第一个。)

extractvalue() 已弃用。你可以用 XMLQuery():

做同样的事情
select XMLQuery(
    '/operationExecutionResponse/rootContext/stringList/string[1]/text()'
    passing r_val
    returning content
  ).getstringval()
into n_id
from dual;

或者您似乎期待一个数字:

select to_number(
    XMLQuery(
      '/operationExecutionResponse/rootContext/stringList/string[1]/text()'
      passing r_val
      returning content
    ).getstringval()
  )
into n_id
from dual;

db<>fiddle

在这两种情况下,都只会从列表中获取第一个 string/number,这是您的原始代码所做的。如果你想获得所有值,你可以使用 XMLTable() 正如@Gnqz 所示,但是(因为你在 PL/SQL 上下文中这样做)你需要 select 那些进入集合或将其转换为游标查询并循环遍历它们 - 取决于您打算在拥有这些值后如何处理这些值。

作为游标你可以这样做:

for r in (
  select n_id
  from XMLTable(
      '/operationExecutionResponse/rootContext/stringList[@name="productIds"]/string'
    passing r_val
    columns n_id number path '.'
  )
)
loop
  -- do something with the value, as r.n_id here
  dbms_output.put_line('Number: ' || r.n_id);
end loop;

db<>fiddle