簡體   English   中英

在Oracle存儲過程中僅解析有效的xml

[英]Parsing only valid xml in Oracle Stored Procedure

我做了一些搜索,但找不到與我嘗試做的相似的情況。

我有以下代碼,該代碼首先構建一個游標,該游標填充有1)xml 2)id。

直到在第二個select語句中擊中了錯誤的xml行之后,此方法才能正常工作,然后它中斷了該過程且不再繼續。 我需要找到一種方法來跳過第二個select語句中的錯誤xml並繼續構建游標。

這是代碼:

DECLARE
COUNTER NUMBER;

CURSOR CXD_ID_UPDATE IS
    WITH
XMLDATA
   AS
(
SELECT XMLTYPE(X.XMLDOC) XMLD, X.CXD_ID
FROM
   C_XML_DOC X RIGHT OUTER JOIN CPS_POT P ON X.CXD_ID = P.CXD_ID 
   WHERE P.CXD_ID IS NOT NULL
)
SELECT XT.SCAN_DOC_ID AS SCAN_DOC_ID
,X.CXD_ID AS CXD_ID
FROM XMLDATA X, CPS_DOCUMENT DOC,
 XMLTABLE('/HXML/BATCH/FOLDER/DOCUMENTS/DOCUMENT'
 PASSING X.XMLD
 COLUMNS SCAN_DOC_ID VARCHAR2(50) PATH '@ScanDocID') XT
 WHERE REGEXP_LIKE(XT.SCAN_DOC_ID,'^\d+(\.\d+)?$', '')
AND XT.SCAN_DOC_ID = DOC.DOC_ID;
BEGIN
COUNTER := 0;
FOR REC IN CXD_ID_UPDATE
LOOP   
BEGIN
  UPDATE DOCUMENT SET CXD_ID = REC.CXD_ID WHERE DOC_ID = REC.SCAN_DOC_ID ; 
  COUNTER := COUNTER + 1;

  EXCEPTION WHEN OTHERS THEN
     CONTINUE; 
  END;
 END LOOP;
 DBMS_OUTPUT.PUT_LINE('UPDATED: ' || COUNTER || ' DOCUMENTS' );
END;

對於那些想要解決這個問題的人。

我首先創建了一個新函數:

create or replace function isWellFormedXML(P_XML_CONTENT CLOB,         
P_ERROR_MESSAGE OUT VARCHAR2)
return number
as
  PARSING_ERROR exception;
  PRAGMA EXCEPTION_INIT( PARSING_ERROR , -31011 );
  V_VALID_XML XMLTYPE;
begin
  V_VALID_XML := XMLTYPE(P_XML_CONTENT);
  V_VALID_XML := NULL;
 return 1;
 exception
 when PARSING_ERROR then
   P_ERROR_MESSAGE := DBMS_UTILITY.FORMAT_ERROR_STACK() ||          DBMS_UTILITY.FORMAT_ERROR_BACKTRACE();
   return 0;
 when others then
   RAISE;
 end;

這是使用該實用程序的主要功能。

DECLARE
 V_ERROR_MSG VARCHAR2(4000);
 COUNTER NUMBER(10);
BEGIN
COUNTER := 0;
FOR R IN (  
SELECT X.CXD_ID CXD,
   X.XMLDOC XML FROM XML_DOC X, POT P WHERE P.CXD_ID = X.CXD_ID
 ) LOOP   
 BEGIN
  IF(isWellFormedXML(R.XML,V_ERROR_MSG)) = 1 THEN
      FOR L IN (
        SELECT D.SCAN_DOC_ID DOCID
        FROM DOCUMENT DOC, xmltable
         ('/HXML/BATCH/FOLDER/DOCUMENTS/DOCUMENT'
            PASSING XMLTYPE.CREATEXML(R.XML)
           COLUMNS SCAN_DOC_ID VARCHAR2(50) PATH '@ScanDocID'  
         ) D  
         WHERE REGEXP_LIKE(D.SCAN_DOC_ID,'^\d+(\.\d+)?$', '')
         AND D.SCAN_DOC_ID = DOC.DOC_ID 
      ) LOOP
      BEGIN
       COUNTER := COUNTER + 1; 
       --DBMS_OUTPUT.put_line('CXD '|| R.CXD || ' DOCID ' || L.DOCID);  
      END;
      END LOOP; 
  END IF;   
  EXCEPTION
     WHEN no_data_found THEN
      NULL;
  END;
END LOOP;     
DBMS_OUTPUT.put_line('TOTAL NUMBER OF DOCUMENTS : ' || COUNTER);
END;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM