Zagorodniy Olexiy Zagorodniy Olexiy - 6 months ago 18
Python Question

Processing error while converting xml to dictionary

Using form i create xml request and receive xml respond that looks like this:

<Root>
<Header>
<information>info</information>
</Header>
<Main>
<Product>
<Name>name1</Name>
<Description>description1</Description>
<Price>1</Price>
</Product>
<Product>
<Name>name2</Name>
<Description>description2</Description>
<Price>2</Price>
</Product>
</Main>
</Root>


Then using this function i convert xml data to dictionary:

from xml.etree import cElementTree as ET
from collections import defaultdict

def etree_to_dict(t):
d = {t.tag: {} if t.attrib else None}
children = list(t)
if children:
dd = defaultdict(list)
for dc in map(etree_to_dict, children):
for k, v in dc.iteritems():
dd[k].append(v)
d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}}
if t.attrib:
d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems())
if t.text:
text = t.text.strip()
if children or t.attrib:
if text:
d[t.tag]['#text'] = text
else:
d[t.tag] = text
return d

e = ET.XML('''
<Root>
<Header>
<information>info</information>
</Header>
<Main>
<Product>
<Name>name1</Name>
<Description>description1</Description>
<Price>1</Price>
</Product>
<Product>
<Name>name2</Name>
<Description>description2</Description>
<Price>2</Price>
</Product>
</Main>
</Root>
''')


And store it to database:

from pprint import pprint
d = etree_to_dict(e)

pprint(d)
d = etree_to_dict(e)

products = d['Root']['Main']['Product']

for p in products:
product = Product()
p.name = p['Name']
p.description = p['Description']
p.price = p['Price']

p.save()


And everything worked fine. But now from time to time i stated to receive messages that looks like this:

<Root>
<Header>
<information>info</information>
</Header>
<Main>
<Error>Product is disable</Error>
</Main>
</Root>


According to this i started to receive this error message:
KeyError at /product/
,
Exception Value: 'Product'
, and traceback
products = d['Root']['Main']['Product']
. So i try to change part of my code to this:

if products = d['Root']['Main']['Product']:
for p in products:
product = Product()
p.name = p['Name']
p.description = p['Description']
p.price = p['Price']
p.save()
else:
pass


But i've got
SyntaxError
in line
if products = d['Root']['Main']['Product']:
. Then I tried to make
products == d['Root']['Main']['Product']
, but now i have another error
local variable 'products' referenced before assignment
. Why does it happen? What i'm doing wrong. Thank you for your answer.

Answer

I will go on and explain the errors you gotten. The syntax error is probably because the "if" is testing a condition, you are not testing a condition but an assignment expression.

The error with the

local variable 'products' referenced before assignment

is because you are testing if the products equal to

d['Root']['Main']['Product']

but products is not even declared

To resolve the errors, you can try the modifying codes of yours below:

try:
 products = d['Root']['Main']['Product']
except KeyError, e:
 print e, "Product is not there"
if products:
 for p in products:
  product = Product()
  p.name = p['Name']
  p.description = p['Description']
  p.price = p['Price']      
  p.save()

else:
     pass

Hope it helps