【问题标题】:parse xml files in root folder and its sub folders解析根文件夹及其子文件夹中的xml文件
【发布时间】:2021-10-08 21:03:31
【问题描述】:

我正在处理一个包含 27 个文件夹和每个文件夹内的各种 XML 文件的目录。

能够:

  • 解析一个 XML 文件并写入一个 CSV 文件
  • 遍历一个文件夹,读取并解析其中的所有XML文件

挑战:

  • 在尝试将所有 XML 文件从根文件夹解析到其子文件夹时遇到问题

发送帮助并感谢您。代码如下:sn-ps

# working in one folder only
import csv
import xml.etree.ElementTree as ET
import os

## directory
path = "/Users.../y"
filenames = []

## Count the number of xml files of each folder
files = os.listdir(path)
print("\n")


xml_data_to_csv = open('/Users.../xml_extract.csv', 'w')
list_head = []
csvwriter = csv.writer(xml_data_to_csv)

# Read XML files in a folder
for filename in os.listdir(path):
    if not filename.endswith('.xml'):
        continue
    fullname = os.path.join(path,filename)
    print("\n", fullname)
    filenames.append(fullname)

# parse elements in each XML file
for filename in filenames:
    tree = ET.parse(filename)
    root = tree.getroot()

    extract_xml=[]

    ## extract child elements per xml file
    print("\n")
    for x in root.iter('Info'):
        for element in x:
            print(element.tag,element.text)
            extract_xml.append(element.text)


    ## Write list nodes to csv
    csvwriter.writerow(extract_xml)

## Close CSV file
xml_data_to_csv.close()

【问题讨论】:

    标签: python parsing elementtree


    【解决方案1】:

    您可以通过

    获取给定路径中所有 XML 文件的列表
    import os
    
    path = "main/root"
    filelist = []
    
    for root, dirs, files in os.walk(path):
        for file in files:
            if not file.endswith('.xml'):
                continue
            filelist.append(os.path.join(root, file))
    
    for file in filelist:
        print(file)
        # or in your case parse the XML 'file'
    

    例如:

    $ tree /main/root
    /main/root
    ├── a
    │   ├── a.xml
    │   ├── b.xml
    │   └── c.xml
    ├── b
    │   ├── d.xml
    │   ├── e.xml
    │   └── x.txt
    └── c
        ├── f.xml
        └── g.xml
    

    我们得到:

    /main/root/c/g.xml
    /main/root/c/f.xml
    /main/root/b/e.xml
    /main/root/b/d.xml
    /main/root/a/c.xml
    /main/root/a/b.xml
    /main/root/a/a.xml
    

    如果要对目录和文件进行排序:

    for root, dirs, files in os.walk(path):
        dirs.sort()
        for file in sorted(files):
            if not file.endswith('.xml'):
                continue
            filelist.append(os.path.join(root, file))
    

    【讨论】:

    • 感谢您清除此问题。非常感谢大家。已经爱上你们了。
    • 另外,在将标题或列名保存到 csv 时,是否有工作流程或方法在解析过程中包含标题或列名?
    • 你应该为此创建一个新帖子。
    【解决方案2】:

    你可以使用os.walk:

    import os
    for dir_name, dirs, files in os.walk('<root_dir>'):
        # parse files
    

    【讨论】:

    • 非常感谢大家。已经爱上你们了
    【解决方案3】:

    您可以使用pathlib 模块来“glob” XML 文件。它将在所有子目录中搜索您提供的模式并返回已包含文件路径的 Path 对象。稍微清理一下你的脚本,你就会有

    import csv
    import xml.etree.ElementTree as ET
    from pathlib import Path
    
    ## directory
    path = Path("/Users.../y")
    
    with open('/Users.../xml_extract.csv', 'w') as xml_data_to_csv:
        csvwriter = csv.writer(xml_data_to_csv)
    
        # Read XML files in a folder
        for filepath in path.glob("**/*.xml"):
            tree = ET.parse(filename)
            root = tree.getroot()
    
            extract_xml=[]
    
            ## extract child elements per xml file
            print("\n")
            for x in root.iter('Info'):
                for element in x:
                    print(element.tag,element.text)
                    extract_xml.append(element.text)
    
            ## Write list nodes to csv
            csvwriter.writerow(extract_xml)
    

    【讨论】:

    • 非常感谢大家。已经爱上你们了
    • 关于如何在 csv 中包含标题或列名的建议或解决方法?
    • @Panda,在创建csvwriter 之后,你可以用csvwriter.writerow(["column 1", "column 2", "column 3"]) 写标题...当然用你的名字代替。
    • 试过了,但它给了我每一行的列名(就像一个循环)
    • @Panda 你想要什么列名?我可以将它添加到示例中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2019-01-02
    • 1970-01-01
    • 2019-02-16
    • 1970-01-01
    • 2020-09-29
    相关资源
    最近更新 更多