Parsování XML v PLPythonu

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

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$