[英]Parsing only valid xml in Oracle Stored Procedure
I have done a bit of searching and can't quite find a similar scenario to what I am trying to do. 我做了一些搜索,但找不到与我尝试做的相似的情况。
I have the following code that first builds a cursor that is filled up with 1) xml 2) id. 我有以下代码,该代码首先构建一个游标,该游标填充有1)xml 2)id。
This works fine until bad xml row is hit (in the second select statement) then it breaks the procedure and does not continue. 直到在第二个select语句中击中了错误的xml行之后,此方法才能正常工作,然后它中断了该过程且不再继续。 I need to find a way to skip bad xml in the second select statement and continue building the cursor.
我需要找到一种方法来跳过第二个select语句中的错误xml并继续构建游标。
Here is the code: 这是代码:
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;
For those that wanted an answer to this here it is. 对于那些想要解决这个问题的人。
I first created a new function: 我首先创建了一个新函数:
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;
This is the main function which utilities this utility. 这是使用该实用程序的主要功能。
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.