简体   繁体   English

如何从 XMLTYPE 中提取第一个节点值?

[英]How can I extract the first node value from a XMLTYPE?

I have a xml which is in a clob field of my table我有一个 xml 在我的表的 clob 字段中

This is the code I am currently using:这是我目前使用的代码:

create table
   xml_key
(  
   mycol number,
   xml   clob
);


insert into xml_key
values(1653,
'<AppHdr>
    <Fr>
      <FIId>
        <FinInstnId>
          <BICFI>CRESUS33</BICFI>
        </FinInstnId>
      </FIId>
    </Fr>
    <To>
      <FIId>
        <FinInstnId>
          <BICFI>CAYTTRISXXX</BICFI>
        </FinInstnId>
      </FIId>
    </To>
    <BizMsgIdr>e9aab4a5-bc32-4548-93f6-aa47dd97d77</BizMsgIdr>
    <MsgDefIdr>pac.004.001.09</MsgDefIdr>
    <BizSvc>swift.cbprplus.02</BizSvc>
    <CreDt>2019-08-12T13:59:26+01:00</CreDt>
    <Rltd>
      <Fr>
        <FIId>
          <FinInstnId>
            <BICFI>LOYDGB21002</BICFI>
          </FinInstnId>
        </FIId>
      </Fr>
      <To>
        <FIId>
          <FinInstnId>
            <BICFI>CRESUS33</BICFI>
          </FinInstnId>
        </FIId>
      </To>
      <BizMsgIdr>1234567890</BizMsgIdr>
        <MsgDefIdr>pacs.008.001.08</MsgDefIdr>
            <CreDt>2019-08-12T12:59:26+01:00</CreDt>
        </Rltd>
    </AppHdr>');

when i extract BIC code from xml i have a problem.当我从 xml 中提取 BIC 代码时,我遇到了问题。 I don't want double nodes like CRESUS33LOYDGB21002 How can I extract only CRESUS33 as FromBIC from xml?我不想要像 CRESUS33LOYDGB21002 这样的双节点如何从 xml 中仅提取 CRESUS33 作为 FromBIC?

 select XMLTYPE(t.xml).EXTRACT('//Fr/FIId/FinInstnId/BICFI/text()').getStringVal()  fromBIC,
     XMLTYPE(t.xml).EXTRACT('//Rltd/Fr/FIId/FinInstnId/BICFI/text()').getStringVal()  RltdFromBIC
          from xml_key t
         where mycol=1653 ;
    
    FROMBIC                           RLTDFROMBIC
    --------------------------------- --------------------------------------
    CRESUS33LOYDGB21002               LOYDGB21002

Thank you谢谢

The problem is you are using //Fr as a shortcut in both extract calls, and as Fr is a node both directly under AppHdr and under AppHdr/Rltd the first XPath matches both of those, and you end up with the values for both combined.问题是您在两个提取调用中都使用//Fr作为快捷方式,并且由于Fr是直接在AppHdr下和AppHdr/Rltd下的节点,因此第一个 XPath 与这两者匹配,并且您最终得到了两者组合的值. The second Xpath is more selective so that only sees the second one.第二个 Xpath 更具选择性,因此只能看到第二个。

If you give the full path for both then you won't have that issue:如果您为两者提供完整路径,那么您将不会遇到该问题:

 select XMLTYPE(t.xml).EXTRACT('/AppHdr/Fr/FIId/FinInstnId/BICFI/text()').getStringVal()  fromBIC,
     XMLTYPE(t.xml).EXTRACT('/AppHdr/Rltd/Fr/FIId/FinInstnId/BICFI/text()').getStringVal()  RltdFromBIC
          from xml_key t
         where mycol=1653 ;

You can also use XMLQuery:您还可以使用 XMLQuery:

select
  XMLQuery('/AppHdr/Fr/FIId/FinInstnId/BICFI/text()'
    passing XMLTYPE(t.xml)
    returning content).getStringVal() as fromBIC,
  XMLQuery('/AppHdr/Rltd/Fr/FIId/FinInstnId/BICFI/text()'
    passing XMLTYPE(t.xml)
    returning content).getStringVal() as RltdFromBIC
from xml_key t
where mycol=1653;

or XMLTable:或 XML 表:

select x.fromBIC, x.RltdFromBIC
from xml_key t
cross apply XMLTable(
  '/AppHdr'
  passing XMLTYPE(t.xml)
  columns
    fromBIC path 'Fr/FIId/FinInstnId/BICFI',
    RltdFromBIC path 'Rltd/Fr/FIId/FinInstnId/BICFI'
) x
where mycol=1653;
FROMBIC弗罗比奇 RLTDFROMBIC RLTDFROMBIC
CRESUS33 CRESUS33 LOYDGB21002 LOYDGB21002

All three return三人皆归

db<>fiddle db<>小提琴


If you're still on a version before 12c then you can use cross join instead of cross apply :如果您仍在使用 12c 之前的版本,则可以使用cross join而不是cross apply

select x.fromBIC, x.RltdFromBIC
from xml_key t
cross join XMLTable(
  '/AppHdr'
  passing XMLTYPE(t.xml)
  columns
    fromBIC path 'Fr/FIId/FinInstnId/BICFI',
    RltdFromBIC path 'Rltd/Fr/FIId/FinInstnId/BICFI'
) x
where mycol=1653;

They aren't exactly the same but shouldn't make a difference here.它们不完全相同,但在这里不应该有所作为。

db<>fiddle db<>小提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM