필자는 XML을 파이썬 데이터 구조로 변환하는 코드를 작성했습니다.하지만 특성을 처리해야했습니다. 비슷한 이유로 ElementTree
대신 xml.dom.minidom
을 사용했습니다. 필자는 Python 2.4.4에서 이것을 실제로 테스트하지는 않았지만 작동 할 것이라고 생각합니다. 역방향 XML 생성기를 작성하지 않았지만, 아마도 이것을 포함하기 위해 'lispy_string'함수를 사용할 수 있습니다.
필자가 작성한 응용 프로그램과 관련된 몇 가지 바로 가기가 포함되어 있지만 (문서화 스트링에 설명되어 있음),이 바로 가기도 소리를 통해 유용하게 사용할 수 있습니다. 본질적으로 xml 트리는 기술적으로 사전 목록 등 사전의 사전 목록으로 번역됩니다. 필요하지 않으면 중개 목록을 작성하지 않으므로 dictname[element1][0][element2][0]
대신 dictname[element1][element2]
등의 요소를 참조 할 수 있습니다.
특성 처리는 다소 번거롭기 때문에 속성을 사용하기 전에 코드를 읽는 것이 좋습니다.
import sys
from xml.dom import minidom
def dappend(dictionary, key, item):
"""Append item to dictionary at key. Only create a list if there is more than one item for the given key.
dictionary[key]=item if key doesn't exist.
dictionary[key].append(item) if key exists."""
if key in dictionary.keys():
if not isinstance(dictionary[key], list):
lst=[]
lst.append(dictionary[key])
lst.append(item)
dictionary[key]=lst
else:
dictionary[key].append(item)
else:
dictionary.setdefault(key, item)
def node_attributes(node):
"""Return an attribute dictionary """
if node.hasAttributes():
return dict([(str(attr), str(node.attributes[attr].value)) for attr in node.attributes.keys()])
else:
return None
def attr_str(node):
return "%s-attrs" % str(node.nodeName)
def hasAttributes(node):
if node.nodeType == node.ELEMENT_NODE:
if node.hasAttributes():
return True
return False
def with_attributes(node, values):
if hasAttributes(node):
if isinstance(values, dict):
dappend(values, '#attributes', node_attributes(node))
return { str(node.nodeName): values }
elif isinstance(values, str):
return { str(node.nodeName): values,
attr_str(node): node_attributes(node)}
else:
return { str(node.nodeName): values }
def xmldom2dict(node):
"""Given an xml dom node tree,
return a python dictionary corresponding to the tree structure of the XML.
This parser does not make lists unless they are needed. For example:
'<list><item>1</item><item>2</item></list>' becomes:
{ 'list' : { 'item' : ['1', '2'] } }
BUT
'<list><item>1</item></list>' would be:
{ 'list' : { 'item' : '1' } }
This is a shortcut for a particular problem and probably not a good long-term design.
"""
if not node.hasChildNodes():
if node.nodeType == node.TEXT_NODE:
if node.data.strip() != '':
return str(node.data.strip())
else:
return None
else:
return with_attributes(node, None)
else:
#recursively create the list of child nodes
childlist=[xmldom2dict(child) for child in node.childNodes if (xmldom2dict(child) != None and child.nodeType != child.COMMENT_NODE)]
if len(childlist)==1:
return with_attributes(node, childlist[0])
else:
#if False not in [isinstance(child, dict) for child in childlist]:
new_dict={}
for child in childlist:
if isinstance(child, dict):
for k in child:
dappend(new_dict, k, child[k])
elif isinstance(child, str):
dappend(new_dict, '#text', child)
else:
print "ERROR"
return with_attributes(node, new_dict)
def load(fname):
return xmldom2dict(minidom.parse(fname))
def lispy_string(node, lst=None, level=0):
if lst==None:
lst=[]
if not isinstance(node, dict) and not isinstance(node, list):
lst.append(' "%s"' % node)
elif isinstance(node, dict):
for key in node.keys():
lst.append("\n%s(%s" % (spaces(level), key))
lispy_print(node[key], lst, level+2)
lst.append(")")
elif isinstance(node, list):
lst.append(" [")
for item in node:
lispy_print(item, lst, level)
lst.append("]")
return lst
if __name__=='__main__':
data = minidom.parse(sys.argv[1])
d=xmldom2dict(data)
print d
나를 위해 옵션을 선택하지 않습니다 그 중 3/4은 외부 라이브러리입니다 그 질문에 :
그것은 다음과 같은 출력을 제공합니다. 마지막 하나는 XML 문서를 마샬링합니다.이 문서는 내가 찾고있는 문서가 아니지만 사전을 먼저 변환하여 보일 것입니다. – Liam