简体   繁体   English

SQL Oracle如何提取blob列中的xml标记内容

[英]SQL Oracle how to extract xml tag content in a blob column

There is an xml that is in a column of type BLOB (in oracle) and I need to access a certain tag from that xml.在 BLOB 类型的列中(在 oracle 中)有一个 xml,我需要从该 xml 访问某个标签。 Until then I can retrieve the column this way:在那之前,我可以通过这种方式检索该列:

SELECT TRIM(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(my_column_blob, 1024))) as tag_name_xml
FROM my_table

the return is like this:回报是这样的: 在此处输入图像描述

Here I leave part of the xml content:这里我留下部分xml内容: 在此处输入图像描述

How do I return the value/content of the cUF or cCT tag?如何返回 cUF 或 cCT 标签的值/内容? I would like the help of people with more knowledge, please.我希望得到更多知识的人的帮助。

the proposed solutions are very elegant, but for my case what would it be like to access with this xml structure to access the contents of the cUF tag?建议的解决方案非常优雅,但对于我来说,使用这个 xml 结构访问 cUF 标签的内容会是什么感觉?

<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.example.com" version="3.00">
   <CTe>
      <infCte version="3.00">
         <ide>
            <cUF>15</cUF>
         </ide>
      </infCte>
   </CTe>
</cteProc>

You can first convert your BLOB data into CLOB type, and then extract the tags you need.您可以先将您的 BLOB 数据转换为 CLOB 类型,然后提取您需要的标签。 Here are two functions that will, hopefully, solve your problem:这里有两个函数,希望能解决你的问题:

FUNCTION BLOB2CLOB(mBLOB IN BLOB) 
    RETURN CLOB IS
BEGIN
    Declare
        mCLOB   CLOB;
        mDestOffSet     INTEGER;
        mSrcOffSet      INTEGER;
        mBLOBCSID       INTEGER;
        mLangCntx       INTEGER;
        mWarn           INTEGER;
    Begin
        mDestOffSet := 1;
        mSrcOffSet := 1;
        mBLOBCSID := 0;
        mLangCntx := 0;
        mWarn := 0;
        DBMS_LOB.CreateTemporary(mCLOB, TRUE);
        DBMS_LOB.ConvertToClob(mCLOB, mBLOB, DBMS_LOB.GetLength(mBLOB), mDestOffSet, mSrcOffSet, mBLOBCSID, mLangCntx, mWarn);
        RETURN(mCLOB);
    End;
END BLOB2CLOB;
--
FUNCTION Get_SOAP_PartCLOB(mCLOB IN CLOB, mTag IN VARCHAR2) RETURN CLOB 
  IS
BEGIN
    Declare
        wrkCLOB         CLOB;
    myStart       NUMBER(10) := 0;
    myEnd         NUMBER(10) := 0;
    myLength      NUMBER(10) := 0;
    toErase       NUMBER(10) := 0;
    Begin
    DBMS_LOB.CreateTemporary(wrkCLOB, True);
    DBMS_LOB.COPY(wrkCLOB, mCLOB, DBMS_LOB.GETLENGTH(mCLOB));
    --
    myStart := DBMS_LOB.InStr(wrkCLOB, mTag, 1, 1) + Length(mTag) - 1;
    myEnd := DBMS_LOB.InStr(wrkCLOB, SubStr(mTag, 1, 1) || '/' || SubStr(mTag, 2));
    myLength := DBMS_LOB.GetLength(wrkCLOB);
    
    DBMS_LOB.ERASE(wrkCLOB, myStart, 1);
    toErase := myLength - myEnd + 1;

    DBMS_LOB.ERASE(wrkCLOB, toErase, myEnd);
    
    wrkCLOB := REPLACE(wrkCLOB, ' ', '');

        RETURN(wrkCLOB);
    End;
END Get_SOAP_PartCLOB;

You can use it like this:你可以像这样使用它:

SELECT 
    Get_SOAP_PartCLOB(BLOB2CLOB(YOUR_BLOB_COL), 'your_tag_in_clob') as "TAG_COL_ALIAS"
FROM
    YOUR_TABLE

I use the second function Get_SOAP_PartCLOB() to get some pretty big B64 data out of the soap envelope response from certain web services.我使用第二个函数 Get_SOAP_PartCLOB() 从某些 Web 服务的肥皂信封响应中获取一些相当大的 B64 数据。 That's why the return type is CLOB.这就是返回类型为 CLOB 的原因。 You can cast the returned value to something else or make your own adjustments to the function.您可以将返回的值转换为其他值或对函数进行自己的调整。

Use XMLTYPE and XMLTABLE :使用XMLTYPEXMLTABLE

SELECT x.c
FROM   table_name t
       CROSS JOIN XMLTABLE(
         '/a/b/c'
         PASSING XMLTYPE(t.value, 1)
         COLUMNS
           c VARCHAR2(200) PATH './text()'
       ) x;

Or XMLQUERY :XMLQUERY

SELECT XMLQUERY('/a/b/c/text()' PASSING XMLTYPE(value, 1) RETURNING CONTENT) AS c
FROM   table_name

Which, for the sample data:其中,对于样本数据:

CREATE TABLE table_name (value BLOB);

INSERT INTO table_name (value)
VALUES ( UTL_RAW.CAST_TO_RAW( '<a><b><c>something</c></b></a>' ) );

Both output:两个输出:

C C
something某物

db<>fiddle here db<> 在这里摆弄

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

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