我的任务是创建将分层数据从postres关系表转换为xml并返回的机制。虽然我没有太多麻烦将表数据转换为xml,但我仍然坚持将实际的xml转换为多个插入。随着postgres提供的文档,我无能为力(。任何帮助将不胜感激。
xml的示例(独立的Button元素和带子节点的Grid):
<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的按钮生成插入语句 806
INSERT INTO TABLE (ID, PARENT_ID,POSITION_IN_PARENT) VALUES (806,NULL,NULL)
然后我将生成一系列GRID及其列(GRDCOL)的插入,
<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)
我无法弄清楚如何遍历xml中的每个节点并仅使用Postgres生成插入。有什么想法吗?
答案 0 :(得分: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;
答案 1 :(得分: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;