使用python批量导出xml文件到csv

Posted

技术标签:

【中文标题】使用python批量导出xml文件到csv【英文标题】:Batch export xml files to csv using python 【发布时间】:2022-01-04 05:36:48 【问题描述】:

我是 python 新手,所以请多多指教一些愚蠢的问题 我有多个以下格式的 xml,我想在这些 xml 中提取某些标签并将它们导出到单个 csv 文件。

这里是 xml (c:\xml\1.xml) 的示例

<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="emotionStyleSheet_template.xsl"?>
<EmotionReport>
    <VersionInformation>
        <Version>8.2.0</Version>
    </VersionInformation>
    <DateTime>
        <Date>18-10-2021</Date>
        <Time>14-12-26</Time>
    </DateTime>
    <SourceInformation>
        <File>
            <FilePath>//nas/emotionxml</FilePath>
            <FileName>file001.mxf</FileName>
            <FileSize>9972536969</FileSize>
            <FileAudioInformation>
                <AudioDuration>1345.0</AudioDuration>
                <SampleRate>48000</SampleRate>
                <NumChannels>8</NumChannels>
                <BitsPerSample>24</BitsPerSample>
                <AudiosampleGroups>64560000</AudioSampleGroups>
                <NumStreams>8</NumStreams>
                <Container>Undefined Sound</Container>
                <Description>IMC Nexio
</Description>
                <StreamInformation>
                    <Stream>
                        <StreamNumber>1</StreamNumber>
                        <NumChannelsInStream>1</NumChannelsInStream>
                        <Channel>
                            <ChannelNumber>1</ChannelNumber>
                            <ChannelEncoding>PCM</ChannelEncoding>
                        </Channel>
                    </Stream>
                    <Stream>
                        <StreamNumber>2</StreamNumber>
                        <NumChannelsInStream>1</NumChannelsInStream>
                        <Channel>
                            <ChannelNumber>1</ChannelNumber>
                            <ChannelEncoding>PCM</ChannelEncoding>
                        </Channel>
                    </Stream>
                </StreamInformation>
                <FileTimecodeInformation>
                    <FrameRate>25.00</FrameRate>
                    <DropFrame>false</DropFrame>
                    <StartTimecode>00:00:00:00</StartTimecode>
                </FileTimecodeInformation>
            </FileAudioInformation>
        </File>
    </SourceInformation>
</EmotionReport>

期望输出结果(EmotionData.csv)

,Date,Time,FileName,Description,FileSize,FilePath
0,18-10-2021,14-12-26,file001.mxf,IMC Nexio,9972536969,//nas/emotionxml
1,13-10-2021,08-12-26,file002.mxf,IMC Nexio,3566536770,//nas/emotionxml
2,03-10-2021,02-09-21,file003.mxf,IMC Nexio,46357672,//nas/emotionxml
....

这是我根据从在线资源 (emotion_xml_parser.py) 中学到的知识编写的代码:

import xml.etree.ElementTree as ET
import glob2
import pandas as pd

cols = ["Date", "Time", "FileName", "Description", "FileSize", "FilePath"]
rows = []
for filename in glob2.glob(r'C:\xml\*.xml'):
  xmlData = ET.parse(filename)
  rootXML = xmlData.getroot()
  for i in rootXML:
    Date = i.findall("Date").text
    Time = i.findall("Time").text
    FileName = i.findall("FileName").text
    Description = i.findall("Description").text
    FileSize = i.findall("FileSize").text
    FilePath = i.findall("FilePath").text

    row.append("Date": Date,
                "Time": Time,
                "FileName": FileName,
                "Description": Description,
                "FileSize": FileSize,
                "FilePath": FilePath,)
df = pd.DataFrame(rows,columns = cols)

# Write dataframe to csv
df.to_csv("EmotionData.csv")

我在运行脚本时收到以下错误

  File "c:\emtion_xml_parser.py", line 14, in <module>
    Date = i.findall("Date").text
AttributeError: 'list' object has no attribute 'text'

TIA!

【问题讨论】:

findall() 返回一个 xml 元素列表。您需要在此列表中选择一个元素才能访问其text 属性。如果您知道只有一个Date 标签,您可以使用i.find("Date").text 而不是findall() @rchome 我最初尝试使用 find(),但出现以下错误:File "c:\emtion_xml_parser.py", line 13, in &lt;module&gt; Date = i.find("Date").text AttributeError: 'NoneType' object has no attribute 'text' 而我所追求的那些标签名称在 xml 中是唯一的 我明白了,所以有些文件可能没有Date 标签。对吗? @rchome 我已经复制了示例文件的 3 个副本,我可以确认它们都包含这些标签。 你试过beautifulsoup吗? 【参考方案1】:

更好的方法是为您需要的每个元素提供完整路径,例如:

import xml.etree.ElementTree as ET
import glob2
import pandas as pd

cols = ["Date", "Time", "FileName", "Description", "FileSize", "FilePath"]
rows = []

for filename in glob2.glob(r'*.xml'):
    xmlData = ET.parse(filename)
    root = xmlData.getroot()
  
    row = 
        'Date' : root.findtext('DateTime/Date'),
        'Time' : root.findtext('DateTime/Time'),
        'FileName' : root.findtext('SourceInformation/File/FileName'),
        'Description' : root.findtext('SourceInformation/File/FileAudioInformation/Description').strip(),
        'FileSize' : root.findtext('SourceInformation/File/FileSize'),
        'FilePath' : root.findtext('SourceInformation/File/FilePath')
    

    rows.append(row)

df = pd.DataFrame(rows, columns=cols)

# Write dataframe to csv
df.to_csv("EmotionData.csv")        

给你:

,Date,Time,FileName,Description,FileSize,FilePath
0,18-10-2021,14-12-26,file001.mxf,IMC Nexio,9972536969,//nas/emotionxml

【讨论】:

太好了,这对我有用。谢谢你。您能否向我解释一下“row = ”的作用?花括号用于在python中定义字典,但在这种情况下它是空的? 它会创建一个空字典,以便在下一行中使用 您也可以直接一次性创建条目,但有时提取值时需要额外的代码

以上是关于使用python批量导出xml文件到csv的主要内容,如果未能解决你的问题,请参考以下文章

java导出大批量(百万以上)数据的excel文件

Python3自动化_文件批量处理(文本PDF;读取筛选导出)

Python3自动化_文件批量处理(文本PDF;读取筛选导出)

Arcgis栅格属性中Source分栏下statistics的所有数值怎么批量导出?

python 批量删除重复图片和其xml文件

批量导出表数据到CSV文件