On 20/02/2014 23:01, Renato Luiz Poleti wrote:
On 20/02/2014 12:38, Matheus de Oliveira wrote:
Renato, sério cara, não faça top-posting, veja as regras da lista:
http://www.postgresql.org.br/RegrasLista
É simples, basta editar a mensagem antes de responder, e ir
respondendo embaixo da mensagem anterior, como vou fazer a seguir:
2014-02-20 11:24 GMT-03:00 Renato Poleti <ren...@poleti.com.br
<mailto:ren...@poleti.com.br>>:
Matheus, eu verifiquei estas funções, mas não conseguir chegar a
uma solução de looping no XML.
Imagina que tenha uma function que recebe como parâmetro o
seguinte XML
<?xml version="1.0? encoding="UTF-8??>
<items>
<item>
<name color="brown">Chair</name>
<price>$53</price>
</item>
<item>
<name color="red">Table Lamp</name>
<price>$10</price>
</item>
</items>
Preciso saber:
a) Quantos itens eu tem.
b) Pegar cada item e fazer um insert em determina tabela (o
problema está no looping)
Lembrando que pode vir 1 item, como varios itens.
Agora sim, posso ajudar melhor... Vamos assumir que tenhas uma função
assim:
CREATE FUNCTION process_item(data xml)
RETURNS TABLE(name text, color text, price text)
...
E ela pega o dado passado via parâmetro e retorna uma linha para cada
item, retornando name, color e price.
O corpo dessa função é bem simples nesse caso. Na verdade nem
precisava de uma função, bastava a seguinte query (que seria também o
corpo da função em linguagem SQL):
SELECT
(xpath('/item/name[1]/text()', item))[1]::text AS name,
(xpath('/item/name[1]/@color', item))[1]::text AS color,
(xpath('/item/price[1]/text()', item))[1]::text AS price
FROM unnest(xpath('/items/item', data)) t(item);
A dica ajudou muito, dei uma lida novamente na documentação e consegui
entender umas coisas.
Eu fiz o exemplo abaixo, e tenho varias tabelas desta forma, todas com
"id e value" e em outro xml (outra tabela) com outros nodes, porem ai
para cada xml teria que fazer cada node na mão;
a) existe alguma outra forma automática de mesclagem
b) tem como melhorar o exemplo abaixo?
c) Vejam que o "name" saiu 2x e não gostaria
c) já achei a resposta, preciso da A) ou B)
SELECT
xmlelement(name items,
xmlagg(
xmlelement(name item,
xmlelement(name id, (xpath('/item/id/text()',
item))[1]::text),
xmlelement(name name,
xmlattributes((xpath('/item/name/@color', item))[1]::text as color),
(xpath('/item/name/text()', item))[1]::text),
xmlelement(name price,
(xpath('/item/price/text()', item))[1]::text),
xmlelement(name value,
(xpath('/item/value/text()', itemb))[1]::text)
)
)
)
...
Exemplo
SELECT
xmlelement(name items,
xmlagg(
xmlelement(name item,
xmlforest (
(xpath('/item/id/text()', item))[1]::text AS id,
xmlelement(name name,
xmlattributes((xpath('/item/name/@color', item))[1]::text as color),
(xpath('/item/name/text()', item))[1]::text) as nome,
(xpath('/item/price/text()', item))[1]::text
AS price,
(xpath('/item/value/text()', itemb))[1]::text
AS val
)
)
)
)
FROM unnest(xpath('/items/item', '<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<id>1</id>
<name color="brown">Chair</name>
<price>$53</price>
</item>
<item>
<id>1</id>
<name color="red">Table Lamp</name>
<price>$10</price>
</item>
<item>
<id>2</id>
<name color="red">Table Lamp</name>
<price>$10</price>
</item>
</items>')) as item
LEFT JOIN
unnest(xpath('/items/item', '<?xml version="1.0" encoding="UTF-8"?>
<items>
<item>
<id>1</id>
<value>xpto</value>
</item>
<item>
<id>1</id>
<value>xpto2</value>
</item>
<item>
<id>2</id>
<value>xpto3</value>
</item>
</items>')) as itemb
ON (xpath('/item/id/text()', item))[1]::text =
(xpath('/item/id/text()', itemb))[1]::text
SAIDA
<items>
<item>
<id>1</id>
<nome>
<name color="brown">Chair</name>
</nome>
<price>$53</price>
<val>xpto2</val>
</item>
<item><id>1</id>
<nome>
<name color="brown">Chair</name>
</nome>
<price>$53</price>
<val>xpto</val>
</item>
<item>
...
</items>
Com isso em mãos, você tem as suas respostas:
a) SELECT count(*) FROM process_item('seu xml');
b) SELECT count(*) FROM process_item('seu xml');
Claro que para (a) tem formas mais performáticas.
Resumindo, estude queries XPath, é a forma mágica de processar XML.
Atenciosamente,
--
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres <http://www.dextra.com.br/postgres/>
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral