Итак, недавно мне пришлось создать конвертер XML в JSON. Он не совсем соответствует стандарту JSON, но подходит довольно близко. Функция xml2json возвращает словарное представление объекта xml. Все атрибуты элемента включены в словарь с ключом атрибутов, а текст элемента включен в текстовый ключ.
Например, ваш xml-объект будет выглядеть после преобразования:
json = {'elements':
{'elem': [
{'attributes': {'id', '1'}, 'text': 'some element'},
{'attributes': {'id', '2'}, 'text': 'some other element'},
{'attributes': {'id', '3'}, 'text': 'some element', 'nested': {
'attributes': {'id', '1'}, 'text': 'other nested element'}},
]}
Вот функция xml2json.
def xml2json(x):
def get_attributes(atts):
atts = dict(atts)
d = {}
for k, v in atts.items():
d[k] = v.value
return d
def get_children(n, d):
tmp = {}
d.setdefault(n.nodeName, {})
if n.attributes:
tmp['attributes'] = get_attributes(n.attributes)
if n.hasChildNodes():
for c in n.childNodes:
if c.nodeType == c.TEXT_NODE or c.nodeName == '#cdata-section':
tmp['text'] = c.data
else:
children = get_children(c, {})
for ck, cv in children.items():
if ck in d[n.nodeName]:
if not isinstance(d[n.nodeName][ck], list):
tmpv = d[n.nodeName][ck]
d[n.nodeName][ck] = []
d[n.nodeName][ck].append(tmpv)
d[n.nodeName][ck].append(cv)
else:
d[n.nodeName][ck] = cv
for tk, tv in tmp.items():
d[n.nodeName][tk] = tv
return d
return get_children(x.firstChild, {})
Вот функция searchjson.
def searchjson(sobj, reg):
import re
results = []
if isinstance(sobj, basestring):
# search the string and return the output
if re.search(reg, sobj):
results.append(sobj)
else:
# dictionary
for k, v in sobj.items():
newv = v
if not isinstance(newv, list):
newv = [newv]
for elem in newv:
has_attributes = False
if isinstance(elem, dict):
has_attributes = bool(elem.get('attributes', False))
res = searchjson(elem, reg)
res = [] if not res else res
for r in res:
r_is_dict = isinstance(r, dict)
r_no_attributes = r_is_dict and 'attributes' not in r.keys()
if has_attributes and r_no_attributes :
r.update({'attributes': elem.get('attributes', {})})
results.append({k: r})
return results
Функция поиска, которую я создал после прочтения вашего вопроса. Он не был проверен на 100% и, возможно, содержит несколько ошибок, но я думаю, что это будет хорошим началом для вас. Что касается того, что вы ищете, он ищет вложенные элементы, атрибуты, используя подстановочные знаки. Он также возвращает идентификатор элементов.
Вы можете использовать эту функцию следующим образом: где xml - это объект xml для поиска, а reg - строка шаблона регулярного выражения для поиска, например: 'other', 'oth. *', '. the. 'все найдут элементы с "другим" в них.
json = xml2json(xml)
results = searchjson(json, reg='other')
Результатами будет список словарей.
Надеюсь, это поможет.