Parsování XML v PLPythonu
Mějme XML ve tvaru:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<ciselnik>
<nazev>kn_i</nazev>
<data>
<radek>
<kn>01011010</kn>
<od>2005-01-01</od>
<do>2011-12-31</do>
<mj_i>PCE</mj_i>
<trida>1</trida>
<tridarim>I</tridarim>
<popis>Živí, čistokrevní, chovní koně</popis>
<popisan>Pure-bred breeding horses</popisan>
</radek>
<radek>
<kn>01011090</kn>
<od>2005-01-01</od>
<do>2011-12-31</do>
<mj_i>PCE</mj_i>
<trida>1</trida>
<tridarim>I</tridarim>
<popis>Živí, čistokrevní, chovní osli</popis>
<popisan>Pure-bred breeding asses</popisan>
</radek>
<radek>
...
Tento dokument chceme převést na tabulku. Po chvilce googlování jsem napsal kód:
CREATE OR REPLACE FUNCTION public.parse_xml(x xml, OUT kn text, OUT od date, OUT "do" date, OUT mj_i text, OUT trida text, OUT tridarim text, OUT popis text, OUT popisan text)
RETURNS SETOF record LANGUAGE plpython2u
AS $function$
import cStringIO
import libxml2
XMLREADER_START_ELEMENT_NODE_TYPE = 1
XMLREADER_TEXT_ELEMENT_NODE_TYPE = 3
XMLREADER_END_ELEMENT_NODE_TYPE = 15
stream = cStringIO.StringIO(x)
input_source = libxml2.inputBuffer(stream)
reader = input_source.newTextReader("urn:bogus")
read_value = False
result = []
while reader.Read():
if reader.NodeType() == XMLREADER_START_ELEMENT_NODE_TYPE:
if reader.LocalName() == "radek": # zacatek datoveho uzlu
read_value = True
row_data = {'trida':None,'tridarim':None} # potencialne prazdne polozky
continue
else:
node_name = reader.LocalName()
if reader.NodeType() == XMLREADER_END_ELEMENT_NODE_TYPE:
if reader.LocalName() == "radek": # opusteni datoveho uzlu
read_value = False
result.append(row_data)
continue
if reader.NodeType() == XMLREADER_TEXT_ELEMENT_NODE_TYPE:
if read_value:
row_data[node_name] = reader.Value()
return result
$function$