从 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;
在这两种情况下,都只会从列表中获取第一个 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;
我正在尝试从 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;
在这两种情况下,都只会从列表中获取第一个 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;