2017-05-17 17 views
-1

这是我想使用的xml文件 我试图创建一个名为'dict1'的字典 它应该包含键“P​​ocket_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 
+0

你在使用ElementTree吗?您还可以添加更多的代码,以便我们看到您如何访问这些元素? –

+0

进口xml.etree.ElementTree如ET 树= ET.parse( 'substation.xml') 根= tree.getroot() 用于child_of_root在根: \t打印child_of_root.tag 它给所有的孩子的根。 在tree.iter()ELEM: \t打印elem.tag,elem.attrib 它给所有的属性 但我不能分开“input_name”和“output_name中”属性 –

+0

@Elango我已经编辑了答案并展示了如何使用ElementTree来完成。请检查。 –

回答

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'] 
} 

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

+0

谢谢@Pablo Gutierrez Marques。有我想要的输出。感谢您的即时帮助 –

+0

Hi @Pablo Gutierrez Marques。我需要字典格式的输出值。 –

+0

''input_layer:fields ['input_name'], output_layer:fields ['output_name'], }'是一个字典。这是否工作,或者你需要一个不同的结构? –

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')]} 

它会给你这样的输出:如果你想使用xml模块,为此,你可以接近这样

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

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

这会给你的相同的输出。

+0

字典应该是什么样子? –

+0

谢谢@salman它为我工作 –

相关问题