2013-06-25 77 views
2


我試圖解析相當大的XML文件。 FILE足夠大,無法使用VARCHAR2,所以我決定使用CLOB。代碼看起來很好,但我仍然遇到錯誤。
下面是XML文件的樣品我解析:
用PL/SQL解析大型XML文件

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<SeznamOvmIndex> 
    <Subjekt> 
     <Zkratka>CUZK</Zkratka> 
     <ICO>00025712</ICO> 
     <Nazev>Český úřad zeměměřický a katastrální</Nazev> 
     <AdresaUradu> 
      <AdresniBod>25133616</AdresniBod> 
      <UliceNazev>Pod sídlištěm</UliceNazev> 
      <CisloDomovni>1800</CisloDomovni> 
      <CisloOrientacni>9</CisloOrientacni> 
      <ObecNazev>Praha</ObecNazev> 
      <ObecKod>554782</ObecKod> 
      <PSC>18200</PSC> 
      <KrajNazev>Hlavní město Praha</KrajNazev> 
     </AdresaUradu> 
     <Email> 
      <Polozka> 
       <Typ text="podatelna">2</Typ> 
       <Email>[email protected]</Email> 
       <Poznamka>Elektronická podatelna ČÚZK</Poznamka> 
      </Polozka> 
     </Email> 
     <TypSubjektu id="11">Orgán státní správy</TypSubjektu> 
     <PravniForma type="325">Organizační složka státu</PravniForma> 
     <PrimarniOvm>Ano</PrimarniOvm> 
     <IdDS>uuaaatg</IdDS> 
     <TypDS>OVM</TypDS> 
     <StavDS>1</StavDS> 
     <StavSubjektu>1</StavSubjektu> 
      <DetailSubjektu>http://seznam.gov.cz/ovm/datafile.do?format=xml&amp;service=seznamovm&amp;id=CUZK</DetailSubjektu> 
    </Subjekt> 
</SeznamOvmIndex> 

這是代碼:
SET SERVEROUTPUT ON

DECLARE 
    xmlClob CLOB; 
    xmlFile UTL_FILE.FILE_TYPE; 
    x XMLType; 
BEGIN 
    xmlFile := UTL_FILE.FOPEN('XMLPARSERADRESYCUZK', 'pokus.xml','R'); 
    LOOP 
    BEGIN 
     UTL_FILE.GET_LINE(xmlFile,xmlClob,NULL); 
    EXCEPTION WHEN No_Data_Found THEN EXIT; END; 
    END LOOP; 
    UTL_FILE.FCLOSE(xmlFIle); 
    x := XMLType.createXML(xmlClob); 
    FOR r IN (
    SELECT ExtractValue(Value(p),'/Subjekt/Zkratka/text()') as kod 
     ,ExtractValue(Value(p),'/Subjekt/AdresaUradu/UliceNazev/text()') as ulice 
     ,ExtractValue(Value(p),'/Subjekt/AdresaUradu/CisloDomovni/text()') as cislo_domovni 
     ,ExtractValue(Value(p),'/Subjekt/AdresaUradu/CisloOrientacni/text()') as cislo_orientacni 
    FROM TABLE(XMLSequence(Extract(x,'/SeznamOvmIndex/Subjekt'))) p 
    WHERE ExtractValue(Value(p),'/Subjekt/Zkratka/text()') = 'CUZK' 
    ) LOOP 
     dbms_output.put_line(r.kod||' '||r.ulice||' '||r.cislo_domovni||'/'||r.cislo_orientacni); 
    END LOOP; 
END; 

我認爲它768,16向右跑,但是當我SQL Developer我得到:

錯誤在第1行 ORA-06512:na「SYS .XMLTYPE「,第5行 ORA-06512:na行13 31011. 00000 - 」XML解析失敗「 *原因:XML解析器在嘗試解析文檔時返回錯誤。 *操作:檢查要解析的文檔是否有效。

+0

<?xml version =「1.0」encoding =「UTF-8」standalONE =「yes」?> 而不是standalONBE – Kotodid

+0

這是轉錄本中的錯誤,而不是數據。問題在別的地方。 –

+0

在我看來,問題不在於XML FILE,而在於CLOB。但我無法弄清楚! –

回答

4

您正在逐行讀取文件,但會覆蓋每行的xmlClob,而不是附加。您可以通過讀入一個varchar2緩衝區和追加建立的CLOB,但你也可以使用DBMS_LOB內置程序來爲你做它:

DECLARE 
    xmlClob CLOB; 
    xmlFile BFILE; 
    x XMLType; 

    src_offset number := 1 ; 
    dest_offset number := 1 ; 
    lang_ctx number := DBMS_LOB.DEFAULT_LANG_CTX; 
    warning integer; 
BEGIN 
    xmlFile := BFILENAME('XMLPARSERADRESYCUZK', 'pokus.xml'); 
    DBMS_LOB.CREATETEMPORARY(xmlClob, true); 
    DBMS_LOB.FILEOPEN(xmlFile, DBMS_LOB.FILE_READONLY); 
    DBMS_LOB.LOADCLOBFROMFILE(xmlClob, xmlFile, DBMS_LOB.LOBMAXSIZE, src_offset, 
    dest_offset, DBMS_LOB.DEFAULT_CSID, lang_ctx, warning); 
    x := XMLType.createXML(xmlClob); 
    DBMS_LOB.FILECLOSEALL(); 
    DBMS_LOB.FREETEMPORARY(xmlClob); 
    FOR r IN (
... 

當我使用並加載文件我得到的輸出:

CUZK Pod smdli.t.m 1800/9 

你可能想圍繞DBMS_LOB調用一些錯誤checkign,這只是一個簡單的演示。

+0

謝謝亞歷克斯,你幫了我很多。 –