【问题标题】:Reading from another child element using Elementree使用 Elementtree 从另一个子元素读取
【发布时间】:2020-01-10 11:33:21
【问题描述】:

下面的代码遍历 xml 文件并将它们解析为单个 csv 文件

from xml.etree import ElementTree as ET
from collections import defaultdict
import csv
from pathlib import Path

directory = 'path to a folder with xml files'

with open('output.csv', 'w', newline='') as f:
    writer = csv.writer(f)

    headers = ['id', 'service_code', 'rational', 'qualify', 'description_num', 'description_txt', 'set_data_xin', 'set_data_xax', 'set_data_value', 'set_data_x']
    writer.writerow(headers)

    xml_files_list = list(map(str, Path(directory).glob('**/*.xml')))
    print(xml_files_list)
    for xml_file in xml_files_list:
        tree = ET.parse(xml_file)
        root = tree.getroot()

        start_nodes = root.findall('.//START')
        for sn in start_nodes:
            row = defaultdict(str)

            repeated_values = dict()
            for k,v in sn.attrib.items():
                repeated_values[k] = v

            for rn in sn.findall('.//Rational'):
                repeated_values['rational'] = rn.text

            for qu in sn.findall('.//Qualify'):
                repeated_values['qualify'] = qu.text

            for ds in sn.findall('.//Description'):
                repeated_values['description_txt'] = ds.text
                repeated_values['description_num'] = ds.attrib['num']

            for st in sn.findall('.//SetData'):
                for k,v in st.attrib.items():
                    row['set_data_'+ str(k)] = v
                for key in repeated_values.keys():
                    row[key] = repeated_values[key]
                row_data = [row[i] for i in headers]
                writer.writerow(row_data)
                row = defaultdict(str)

这是xml文件。

<?xml version="1.0" encoding="utf-8"?>
<ProjectData>
 <Phones>
    <Date />
    <Prog />
    <Box />
    <Feature />
    <IN>MAFWDS</IN>
    <Set>234234</Set>
    <Pr>23423</Pr>
    <Number>afasfhrtv</Number>
    <Simple>dfasd</Simple>
    <Nr />
    <Get>6070106091</Get>
    <Reno>1233</Reno>
  </Phones>
<FINAL>
    <START id="B001" service_code="0x5196">
      <Docs Docs_type="START">
        <Rational>225196</Rational>
        <Qualify>6251960000A0DE</Qualify>
      </Docs>
      <Description num="1213f2312">The parameter</Description>
      <DataFile dg="12" dg_id="let">
        <SetData value="32" />
      </DataFile>
    </START>
    <START id="C003" service_code="0x517B">
      <Docs Docs_type="START">
        <Rational>23423</Rational>
        <Qualify>342342</Qualify>
      </Docs>
      <Description num="3423423f3423">The third</Description>
      <DataFile dg="55" dg_id="big">
        <SetData x="E1" value="21259" />
        <SetData x="E2" value="02" />
      </DataFile>
    </START>
    <START id="Z048" service_code="0x5198">
      <RawData rawdata_type="ASDS">
        <Rational>225198</Rational>
        <Qualify>343243324234234</Qualify>
      </RawData>
      <Description num="434234234">The forth</Description>
      <DataFile unit="21" unit_id="FEDS">
        <FileX unit="eg" discrete="false" axis_pts="19" name="Vsome" text_id="bx5" unit_id="GDFSD" />
        <SetData xin="5" xax="233" value="323" />
        <SetData xin="123" xax="77" value="555" />
        <SetData xin="17" xax="65" value="23" />
      </DataFile>
    </START>
</FINAL>
</ProjectData>

这是输出的样子

目前正在努力修改代码,所以它转到 Phones(它是 Projectdata 的另一个子项)从 SetGet 获取元素将它们与 _ 一起附加并将它们解析到具有标题名称的第一列**识别** 下图显示了它的外观。

【问题讨论】:

    标签: python pandas elementtree


    【解决方案1】:

    将您的headers 行修改为

    headers = ['identify', 'id', 'service_code', 'rational', 'qualify', 'description_num', 'description_txt', 'set_data_xin', 'set_data_xax', 'set_data_value', 'set_data_x']
    
    p_get = tree.find('.//Phones/Get').text
    p_set = tree.find('.//Phones/Set').text
    

    并将此信息添加到 row_data 中,就在 writer.writerow(row_data) 行之前

    像这样:

    row_data.insert(0, p_get + '_' + p_set)
    

    更新

    row_data[0] = p_get + '_' + p_set
    

    【讨论】:

    • 我在 writer.writerow(headers) 之前添加了 row_data.insert(0, p_get + '' + p_set)_ 。那么 p_get = tree.find('.//Phones/Get').text 应该把这两个粘贴到哪里
    • 你能帮我看看我必须在哪里添加行吗?我没有在任何地方声明 row_data
    • @ebe 在root = tree.getroot() 之后添加pget = ...p_set = ...,在row_data = [row[i] for i in headers] 之后添加row_data.insert( ... )
    • @Valentino,我应该在哪里添加 row_data = [row[i] for i in headers]
    • @Valentino,当我在标题中添加了标识时,下一列是空的,其他所有内容都移动了一列。在输出上可以看到pasteboard.co/IPKPldQ.png
    猜你喜欢
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 2012-05-11
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2018-04-12
    相关资源
    最近更新 更多