oracle 如何在NS标签之间使用extractvalue获取XML中的数据

gblwokeq  于 2023-03-01  发布在  Oracle
关注(0)|答案(1)|浏览(78)

我正在处理下面的xml。我需要这个数据--〉“12574017”

<ns0:AvlABC xmlns="http://xmlns.zzz.com/xxx/aaa/ZOZSE/POwn" 
xmlns:ns7="http://xmlns.zzz.com/xxx/aaa/ZOZ/POwn" 
xmlns:ns1="http://xmlns.zzz.com/xxx/aaa/ZOZSE/COwn" 
xmlns:ns0="http://xmlns.zzz.com/xxx/aaa/ZOZSE/OOwn" 
xmlns:ns2="http://xmlns.zzz.com/xxx/aaa/ZOZ/COwn">
    <ns2:RequestInfoBP>
        <ns2:TypeId>sales1</ns2:TypeId>
        <ns2:Code>SALE_ORD</ns2:Code>
        <ns2:Date>2016/03/02-18:47:32</ns2:Date>
        <ns2:Id>525810007</ns2:Id>
        <ns2:MDI>
            <ns2:CINFO>
                <ns2:CUSERID/>
                <ns2:CUSERID/>
            </ns2:CINFO>
            <ns2:UINFO>
                <ns2:UpdateDate>2016/03/02-18:47:44</ns2:UpdateDate>
                <ns2:UpdateUser>936455507</ns2:UpdateUser>
            </ns2:UINFO>
        </ns2:MDI>
        <ns2:InqType>VRF_INQ</ns2:InqType>
    </ns2:RequestInfoBP>
    <ns0:Prdtype>
        <ns7:ProductKey>
            <ns7:PrdId>22627705</ns7:PrdId>
        </ns7:ProductKey>
        <ns7:DptPrd>
            <ns7:PrdId>2150905</ns7:PrdId>
            <ns7:FlsValueName>
                <ns7:FlsCharId>7125</ns7:FlsCharId>
                <ns7:FlsCharName>txn_fon_id</ns7:FlsCharName>
                <ns7:FlsValueId>9352727</ns7:FlsValueId>
                <ns7:FlsName>txn_fon_asd</ns7:FlsName>
                <ns7:FlsValueNameBI>11237118</ns7:FlsValueNameBI>
            </ns7:FlsValueName>
            <ns7:FlsValueName>
                <ns7:FlsCharId>30188302</ns7:FlsCharId>
                <ns7:FlsCharName>txn_sd_id</ns7:FlsCharName>
                <ns7:FlsValueId>12574017</ns7:FlsValueId>
                <ns7:FlsName>txn_sd_asd</ns7:FlsName>
                <ns7:FlsValueNameBI>1235858</ns7:FlsValueNameBI>
            </ns7:FlsValueName>
        </ns7:DptPrd>
    </ns0:Prdtype>
</ns0:AvlABC>

我可以用substr和instr方法得到这个值

select to_char(substr(A.DATA,instr(A.DATA,'txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')+length('txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>'),
instr(A.DATA,'\</ns7:FlsValueId\>\<ns7:FlsName\>txn_sd_asd')-instr(A.DATA,'txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')-length('txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')))
value , a.* from temp_xx a

但是“ns 7”字段是可变状态的。因为它有时候有时候可以ns7:FlsValueId像这样ns8:FlsValueIdns2:FlsValueIdns14:FlsValueId等等。
我想我必须使用XPath和extractvalue,但是我不能。
如何从变量“ns”标签中获取此数据(使用extractvalue或其他方法)?

select to_char(substr(A.DATA,instr(A.DATA,'txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')+length('txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>'),
instr(A.DATA,'\</ns7:FlsValueId\>\<ns7:FlsName\>txn_sd_asd')-instr(A.DATA,'txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')-length('txn_sd_id\</ns7:FlsCharName\>\<ns7:FlsValueId\>')))
value , a.* from temp_xx a
x759pob2

x759pob21#

The extractvalue() function已被弃用,因此实际上不应使用它。
您可以使用XMLQuery,其Xpath忽略名称空间,因为您不知道需要哪个名称空间:

select xmlquery(
  '//*:FlsValueName[*:FlsCharName="txn_sd_id"]/*:FlsValueId/text()'
  passing xmltype(a.data)
  returning content).getStringVal() as id
from temp_xx a

| 识别号|
| - ------|
| 小行星1257|
fiddle
如果data列已经是XMLType,而不是CLOB或varchar 2,则不需要xmltype()转换调用。
XPath查找具有值为“txn_sd_id”的子FlsCharName节点的FlsValueName节点;然后从匹配的FlsValueName下的FlsValueId节点获取值。所有节点引用都以*:通配符命名空间为前缀,因此它们可以匹配任何名称空间,甚至不需要将命名空间声明为XPath的一部分。
节点的文本内容以字符串形式返回;如果您需要这种数据类型,则可以通过将XMLQuery Package 在to_number()中将其转换为数字。
如果您实际上计划提取多个值,则可以改用XMLTable。例如:

select x.*
from temp_xx a
cross apply xmltable(
  '//*:FlsValueName'
  passing xmltype(a.data)
  columns
    prdid number path './../*:PrdId',
    flscharid number path '*:FlsCharId',
    flscharname varchar2(10) path '*:FlsCharName',
    flsvalueid number path '*:FlsValueId',
    flsname varchar2(10) path '*:FlsName',
    flsvaluenamebi number path '*:FlsValueNameBI'
) x

| PRDID|弗尔沙里德|文件名|失效值ID|文件名|最低价值|
| - ------|- ------|- ------|- ------|- ------|- ------|
| 小行星2150905|小行星7125|事务处理类型标识|小行星935|事务处理_字体_as|小行星112|
| 小行星2150905|小行星30188302|事务处理_sd_id|小行星1257|事务处理_sd_asd|小行星1235858|
fiddle
您可以在columns子句中指定数据类型(包括字符串的合理大小),并且我已经包含了一个示例,说明如何沿着节点树返回以从更高级别获取PrdId。如果您有多个级别,每个级别都有多个值,则嵌套XMLTable调用是一种更有用的方法。

相关问题