“我希望将结果放在支持以下功能的课程中:......”

时间:2017-05-17 11:56:37

标签: python xml dictionary

这是我想要使用的xml文件 我试着创建一个名为'dict1'的字典 它应该包含键'Pocket_substation'和'sub_substation' 第一个密钥Pocket_substation应包含所有input_names,sub_substation密钥应包含所有output_names。

<input_layer name = "Pocket_Substation"/>

<output_layer name = "sub_substation"/>

<field_mapping>

    <field input_name = "dat"  output_name="date" />

    <field input_name = "Type"  output_name="type"/>

    <field input_name = "Class"  output_name="class"/>

    <field input_name = "Land"  output_name="land"/>

    <field input_name = "status"  output_name="status"/>

    <field input_name = "descrp"  output_name="description"/>

    <field input_name = "Loc"  output_name="location"/>

    <field input_name = "voltage" output_name="voltage"/>

    <field input_name = "name"  output_name="owner_name"/>


    <field input_name = "Remarks"  output_name="remarks"/>

</field_mapping>

并选择我写的所有input_names

for elem in tree.iter(tag='field'):

print elem.attrib

for ele in elem.attrib(tag='input_name'):

    print ele.attrib

但它只打印第一个值。有人帮我解决这个问题 代码中的函数:

def read_field(xml_node, name):

return [child.get(name) for child in xml_node.iter('field')]

def read_map(xml_node):

f = root.attrib

dict1 = {f['name']:['input_layer','output_layer','fields']}

dict1[f['name']][0] = {'input_layer':root.find('input_layer').get('name')}

dict1[f['name']][1] = {'output_layer':root.find('output_layer').get('name')}

for child in xml_node:

    if child.tag == 'field_mapping':

        fields = {field_name : read_field(child, field_name) for field_name 

                 in ['input_name','output_name']}

        dict1[f['name']][2] = 

        {'fields':dict(zip(fields['output_name'],fields['input_name']))}

return dict1

2 个答案:

答案 0 :(得分:2)

您可以使用BeautifulSoup来解析xml。这很方便。

from bs4 import BeautifulSoup

soup = BeautifulSoup(your_xml, 'xml')

print {soup.find('input_layer').get('name'): [item.get('input_name') for item in soup.find_all('field')]}

它会给你一个这样的输出:

{u'Pocket_Substation': [u'dat',
  u'Type',
  u'Class',
  u'Land',
  u'status',
  u'descrp',
  u'Loc',
  u'voltage',
  u'name',
  u'Remarks']}

如果你想使用xml模块,你可以这样做:

{root.find('input_layer').get('name'): [item.get('input_name') for item in list(root.find('field_mapping'))]}

这会给你相同的输出。

答案 1 :(得分:1)

首先,您需要将XML条目包装在......之类的内容中,否则它在语法上不正确。

除此之外,您可以像这样解析映射:

import xml.etree.ElementTree as ET

def read_field_attributes(xml_node, name):
    return [child.get(name) for child in xml_node.iter('field')]

def read_mapping(xml_node):
    # reset the variables
    input_layer = None
    output_layer = None
    fields = dict()
    # loop over the first level nodes and store the values
    for child in xml_node:
        if child.tag == 'field_mapping':
            # read the input and output fields separate but in order
            fields = {field_name : read_field_attributes(child, field_name) for field_name in ['input_name', 'output_name']}
        elif child.tag == 'input_layer':
            # read the name of the input layer
            input_layer = child.get('name')
        elif child.tag == 'output_layer':
            # read the name of the output layer
            output_layer = child.get('name')
    # if all the information is provided, build the mapping
    if input_layer is not None and output_layer is not None and len(fields) == 2:
        return {
            input_layer : fields['input_name'],
            output_layer : fields['output_name'],
        }
    # otherwise, return an empty dictionary
    return {}

tree = ET.parse('substation.xml')
root = tree.getroot()
print(read_mapping(root))

输出为

{
    'Pocket_Substation': 
        ['dat', 'Type', 'Class', 'Land', 'status', 'descrp', 'Loc', 'voltage', 'name', 'Remarks'], 
    'sub_substation': 
        ['date', 'type', 'class', 'land', 'status', 'description', 'location', 'voltage', 'owner_name', 'remarks']
}

然而,解析和存储输入和输出参数有点危险,因为其中一个字段可能有输入而没有输出,反之亦然,在解析过程中你不会知道它。相反,我建议使用字典将输入映射到输出,这样每个输入对应一个输出而只有一个。