2017-02-26 9 views
0

postresのリレーショナルテーブルからxmlとbackに階層データを変換する仕組みを作成しました。テーブルのデータをxmlに変換するのにはあまり問題はありませんでしたが、実際のxmlを複数の挿入に変換することに悩まされています。 。私は何もしない可能性はpostgresに付属のマニュアルで(任意の助けをいただければ幸いXML(子供を持つ独立したボタンの要素とグリッド)のpostgresqlで挿入を作成するためにxmlを解析する

例:。

<BTN> 
    806 
    <BTN_WINDOW /> 
</BTN> 
<GRID> 
    217 
    <GRID_COLUMNS> 
     <GRDCOL visible="true" vl_order="0" 
      description="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params>some info</vl_svc_params> 
      226 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="1" 
      title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params_1>some info</vl_svc_params> 
      218 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="2" title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_svc_params>some info</vl_svc_params> 
      219 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="3" 
      title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params>some info</vl_svc_params> 
      220 
     </GRDCOL> 
    </GRID_COLUMNS> 
</GRID> 

を、XMLを解析した後、私はしていますID 806

INSERT INTO TABLE (ID, PARENT_ID,POSITION_IN_PARENT) VALUES (806,NULL,NULL) 

とボタンの挿入文を生成それから私は、GRID及びそのCOLのインサートのシリーズを生成することになっています私はPostgresの有するインサートをXML内の各ノードをトラバースし、生成するための方法を考え出すことができない

<GRID> 
    217 
    <GRID_COLUMNS> 
     <GRDCOL visible="true" vl_order="0" 
      description="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params>some info</vl_svc_params> 
      226 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="1" 
      title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params_1>some info</vl_svc_params> 
      218 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="2" title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_svc_params>some info</vl_svc_params> 
      219 
     </GRDCOL> 
     <GRDCOL visible="true" vl_order="3" 
      title="some description"> 
      <vl_props>some info</vl_props> 
      <vl_params>some info</vl_svc_params> 
      220 
     </GRDCOL> 
    </GRID_COLUMNS> 
</GRID> 

INSERT INTO TABLE (ID, PARENT_ID,POSITION_IN_PARENT) 
VALUES (217,NULL,NULL) --grid itself 
INSERT INTO TABLE (ID, PARENT_ID, POSITION_IN_PARENT) 
VALUES (226,217,GRID_COLUMNS) 
INSERT INTO TABLE (ID, PARENT_ID, POSITION_IN_PARENT) 
VALUES (218,217,GRID_COLUMNS) 
INSERT INTO TABLE (ID, PARENT_ID, POSITION_IN_PARENT) 
VALUES (219,217,GRID_COLUMNS) 
INSERT INTO TABLE (ID, PARENT_ID, POSITION_IN_PARENT) 
VALUES (220,217,GRID_COLUMNS) 

umns(GRDCOL)。何か案は?

+1

ようこそ。 [ツアー]を読んで、[質問する]を読んで、[mcve]を投稿してください。この質問は広すぎます。 – OldProgrammer

+0

私の悪い、いくつかの編集を加えました。アドバイスありがとうございます。 –

答えて

0

ソリューションは非常に簡単です。

まず、現在のxmlには何人の子供がいるか調べます。

SELECT btrim(xpath('count(./*)', 
        p_input_xml, 
        ARRAY [ ARRAY [ 'el', 
        'http://example.com' ], 
        array [ 'p', 
        'http://example1.com' ] ]) ::text, 
       '{}') 
    into v_child_count; 

次に、子供を反復して、再帰的に子供の子を見つけるなどします。したがって、xmlをより小さいxmlに細断します。

select replace(btrim(xpath(format('./*[%s]', CURRENT_CHILD_ID), 
           p_input_xml, 
           ARRAY [ ARRAY [ 'el', 
           'http://example.com' ] ]) ::text, 
         '"{}"'), 
        '\"', 
        '"') ::xml 
     into v_child_xml; 
0

XML文書を解析するのが少し難しくなります。しかし、それは可能です。

XPATHの機能を使用することができます。これは、大型のドキュメントにも十分速く、良いです。文書の

のような:

 
<?xml version="1.0" encoding="windows-1250"?> 
<enprimeur> 
     <vino> 
      <id>1</id> 
      <nazev>Alter Ego de Palmer</nazev> 
      <vyrobce>63</vyrobce> 
      <rocnik>2012</rocnik> 
      <cena0375>0</cena0375> 
      <cena1500>0</cena1500> 
      <cena3000>0</cena3000> 
      <cena6000>0</cena6000> 
      <cena0750>1425</cena0750> 
      <cenastart>1085</cenastart> 
      <min0375>0</min0375> 
      <min0750>0</min0750> 
      <odrudy>51 % Merlot, 40 % Cabernet Sauvignon,9 % Petit Verdot</odrudy> 
      <bestin>2017 - 2026</bestin> 
      <klas>2</klas> 
      <sklad0375>0</sklad0375> 
      <sklad0750>0</sklad0750> 
      <sklad1500>0</sklad1500> 
      <sklad3000>0</sklad3000> 
      <sklad6000>0</sklad6000> 
      <alk>13,4 %</alk> 
      <remark>Premiant oblasti Margaux Ch. Palmer tentokrát ve svých obou vínech tì.il z dokonale zralého Merlotu, kterého do svých smìsí naládova 
      <rating>Robert Parker: /100 
TOPVINO SCORE: 92-94/100 
James Suckling: 92-93/100 
Wine Spectator: 90-93/100</rating> 
      <zalozeno></zalozeno> 
      <rozloha></rozloha> 
      <stari></stari> 
      <puda></puda> 
      <produkce></produkce> 
      <zrani></zrani> 
      <active>1</active> 
      <stitky> 
      <stitek>8</stitek> 
      <stitek>1</stitek> 
      </stitky> 
     </vino> 
     <vino> 
    ... 

あなたはq個のクエリを使用することができます。私が出会った

 
select x[1]::int id, x[2] nazev, x[3] vyrobce, 
     x[4]::int rocnik, x[5]::double precision cena0375, 
     x[6]::double precision cena1500, x[7]::double precision cena3000, 
     x[7]::double precision cena6000, x[8]::double precision cena0750, 
     x[9]::double precision cenastart, x[10]::double precision min0375, 
     x[11]::double precision min0750, x[12] alk, x[13] klas 
    from (select xpath('/vino/id/text()|' 
'/vino/nazev/text()|/vino/vyrobce/text()|/vino/rocnik/text()|' 
'/vino/cena0375/text()|/vino/cena1500/text()|/vino/cena3000/text()|' 
'/vino/cena6000/text()|/vino/cena0750/text()|/vino/cenastart/text()|' 
'/vino/min0375/text()|/vino/min0750/text()|/vino/alk/text()|' 
'/vino/klas/text()', v)::text[] x 
      from (select unnest(xpath('/enprimeur/vino', d)) from xmldata) g(v)) s; 
+0

ありがとうございますが、私の場合、xmlはダイナミックに形成されています。私は事前にその構造を知りません。 –

+0

@ Vad Boro、どのように構造がわからない文書を解析できますか? – OldProgrammer

関連する問題