从嵌套 XML PostgreSQL 中提取数据
Extracting data from nested XML PostgreSQL
我有一个 XML 需要插入 table。 XML 看起来像
<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
<pat>
<id>1</id>
<pat_maps>
<pat_map>
<pgid>100</pgid>
<pgname>test</pgname>
</pat_map>
<pat_map>
<pgid>101</pgid>
<pgname>test1</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>2</id>
<pat_maps>
<pat_map>
<pgid>102</pgid>
<pgname>test2</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>3</id>
<pat_maps>
<pat_map>
<pgid>104</pgid>
<pgname>test6</pgname>
</pat_map>
<pat_map>
<pgid>105</pgid>
<pgname>test7</pgname>
</pat_map>
</pat_maps>
</pat>
</pats>
</root>
我想按以下方式插入数据
ID pgid pgname
1 100 test
1 101 test1
2 102 test2
3 104 test6
3 105 test7
在下面尝试过,但它正在应用交叉连接
with x(t) as (select '<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
..............
..........
</pat>
</pats>
</root>'::xml AS t
)
, base_id as (SELECT
unnest(xpath('/root/pats/pat/id/text()', t)) AS id
from x
), nested_rec as ( select
unnest(xpath('pgid/text()', cat_assn_list)) AS pgid,
unnest(xpath('pgname/text()', cat_assn_list)) AS pgname
from (select unnest(xpath('/root/pats/pat/pat_maps/pat_map', t)) cat_assn_list from x) q
)
select base_id.*,nested_rec.* from base_id,nested_rec;
******* output *********
ID PGID PGNAME
"1" "100" "test"
"1" "101" "test1"
"1" "102" "test2"
"1" "104" "test6"
"1" "105" "test7"
"2" "100" "test"
"2" "101" "test1"
"2" "102" "test2"
"2" "104" "test6"
"2" "105" "test7"
"3" "100" "test"
"3" "101" "test1"
"3" "102" "test2"
"3" "104" "test6"
"3" "105" "test7"
我还没有找到方法,如何明智地嵌套 XML ID 并准备结果集?。
有没有其他方法可以在不使用 PostgreSQL 中的 XPath 函数的情况下将 xml 数据转换为 table?
提前致谢。
以下是您想要的,并且更短一些:
select (xpath('/pat/id/text()', d.pat))[1]::text::int as id,
(xpath('/pat_map/pgid/text()', m.map))[1]::text::int as pgid,
(xpath('/pat_map/pgname/text()', m.map))[1]::text as pgname
from x
cross join unnest(xpath('/root/pats/pat', x.t)) as d(pat)
cross join unnest(xpath('/pat/pat_maps/pat_map', d.pat)) as m(map)
;
对于更现代的 Postgres 版本,您可以使用 xmltable()
:
select d.*
from x
cross join xmltable ('/root/pats/pat/pat_maps/pat_map'
passing t
columns
id integer path '../../id',
pgid integer path 'pgid',
pgname text path 'pgname') as d
我有一个 XML 需要插入 table。 XML 看起来像
<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
<pat>
<id>1</id>
<pat_maps>
<pat_map>
<pgid>100</pgid>
<pgname>test</pgname>
</pat_map>
<pat_map>
<pgid>101</pgid>
<pgname>test1</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>2</id>
<pat_maps>
<pat_map>
<pgid>102</pgid>
<pgname>test2</pgname>
</pat_map>
</pat_maps>
</pat>
<pat>
<id>3</id>
<pat_maps>
<pat_map>
<pgid>104</pgid>
<pgname>test6</pgname>
</pat_map>
<pat_map>
<pgid>105</pgid>
<pgname>test7</pgname>
</pat_map>
</pat_maps>
</pat>
</pats>
</root>
我想按以下方式插入数据
ID pgid pgname
1 100 test
1 101 test1
2 102 test2
3 104 test6
3 105 test7
在下面尝试过,但它正在应用交叉连接
with x(t) as (select '<?xml version="1.0" encoding="UTF-8"?>
<root>
<pats>
..............
..........
</pat>
</pats>
</root>'::xml AS t
)
, base_id as (SELECT
unnest(xpath('/root/pats/pat/id/text()', t)) AS id
from x
), nested_rec as ( select
unnest(xpath('pgid/text()', cat_assn_list)) AS pgid,
unnest(xpath('pgname/text()', cat_assn_list)) AS pgname
from (select unnest(xpath('/root/pats/pat/pat_maps/pat_map', t)) cat_assn_list from x) q
)
select base_id.*,nested_rec.* from base_id,nested_rec;
******* output *********
ID PGID PGNAME
"1" "100" "test"
"1" "101" "test1"
"1" "102" "test2"
"1" "104" "test6"
"1" "105" "test7"
"2" "100" "test"
"2" "101" "test1"
"2" "102" "test2"
"2" "104" "test6"
"2" "105" "test7"
"3" "100" "test"
"3" "101" "test1"
"3" "102" "test2"
"3" "104" "test6"
"3" "105" "test7"
我还没有找到方法,如何明智地嵌套 XML ID 并准备结果集?。 有没有其他方法可以在不使用 PostgreSQL 中的 XPath 函数的情况下将 xml 数据转换为 table? 提前致谢。
以下是您想要的,并且更短一些:
select (xpath('/pat/id/text()', d.pat))[1]::text::int as id,
(xpath('/pat_map/pgid/text()', m.map))[1]::text::int as pgid,
(xpath('/pat_map/pgname/text()', m.map))[1]::text as pgname
from x
cross join unnest(xpath('/root/pats/pat', x.t)) as d(pat)
cross join unnest(xpath('/pat/pat_maps/pat_map', d.pat)) as m(map)
;
对于更现代的 Postgres 版本,您可以使用 xmltable()
:
select d.*
from x
cross join xmltable ('/root/pats/pat/pat_maps/pat_map'
passing t
columns
id integer path '../../id',
pgid integer path 'pgid',
pgname text path 'pgname') as d