使用Python从XML中提取属性

时间:2012-09-07 23:06:01

标签: python xml xml-parsing

我想使用此代码从xml文件中提取属性 xml文件是:

xml= "<graphics type='xxx' port=’0’ autoport='xxx' listen='0.0.0.0'>
  <listen type='address' address='0.0.0.0'/>
</graphics>"

,代码是:

def xml_to_dict(xml):  
      d={}   
      if xmlk.text:
         d[xmlk.tag] = xmlk.text  
      else:
         d[xmlk.tag] = {}   
     children = xmlk.getchildren()   
     if children:
         d[xmlk.tag] = map(xml_to_dict, children)  
         return d

     xml_to_dict(xyz) Output: {'graphics': [{'listen': {}}]}

我尝试过dmlk,attrib而不是tag但无济于事。有谁知道这个

3 个答案:

答案 0 :(得分:0)

from lxml import etree
dict(etree.fromstring(xml).items())

输出

{'autoport': 'xxx', 'type': 'xxx', 'port': '0', 'listen': '0.0.0.0'}

答案 1 :(得分:0)

我建议使用lxml,但以下代码适用于lxml或ElementTree

您还需要稍微调整一下您的算法:

from xml.etree import ElementTree as etree
tree = etree.fromstring(xml)

def xml_to_dict(tree):  
  d={}   
  if tree.text:
     d[tree.tag] = tree.text  
  elif len(tree) < 0:
     d[tree.tag] = {}   
  else:   
     d[tree.tag] = map(xml_to_dict, tree)  
 return d

这可以满足您的要求。

答案 2 :(得分:0)

目前尚不清楚您想要使用的输出格式。这是尝试接近您的代码的一种可能性:

empty = lambda s: not (s and s.strip())

def xml_to_dict(root):
    assert empty(root.tail), 'tail is not supported'
    d = root.attrib
    assert root.tag not in d, 'tag and attribute name conflict'
    if len(root) > 0: # has children
       assert empty(root.text), 'text and chilren conflict'
       d[root.tag] = map(xml_to_dict, root)
    elif not empty(root.text):
       d[root.tag] = root.text
    return d

在一般情况下,这是不可逆的。

实施例

import pprint
import xml.etree.ElementTree as etree

xml = """<graphics type='xxx' port='0' autoport='xxx' listen='0.0.0.0'>
  <listen type='address' address='0.0.0.0'/>
 <value>1</value>
 <blank/>
</graphics>
"""
pprint.pprint(xml_to_dict(etree.fromstring(xml)))

输出

{'autoport': 'xxx',
 'graphics': [{'address': '0.0.0.0', 'type': 'address'}, {'value': '1'}, {}],
 'listen': '0.0.0.0',
 'port': '0',
 'type': 'xxx'}

注意:<listen>列表中不存在graphics标记名称,其中<blank/>缩减为{}