所以,最近我不得不创建一个 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% 的测试,可能有一些错误,但我认为这对你来说是一个好的开始。至于您要查找的内容,它使用通配符搜索嵌套元素、属性。它还返回元素的 id。
您可以像这样使用该函数,其中 xml 是要搜索的 xml 对象,而 reg 是要搜索的正则表达式模式字符串,例如:'other', 'oth.*', '.the.' 将找到其中包含“其他”的元素。
json = xml2json(xml)
results = searchjson(json, reg='other')
results 将是一个字典列表。
希望对你有帮助。