【问题标题】:Python combining html and xml files into a single dictionaryPython 将 html 和 xml 文件组合成一个字典
【发布时间】:2021-07-25 18:23:06
【问题描述】:

我正在尝试将 html 文件(文本)和 xml 文件(元数据)组合成一个平面字典,我将把它写为 Json。这些文件包含在同一文件夹中,并具有以下名称结构:

  • abcde.html
  • abcde.html.xml

这是我的简化代码,我的问题是我必须将 xml 元数据写入分开

        ### Create a list of dict with one dict per file, first write file content then meta-data

        for path, subdirs, files in os.walk("."):
            for fname in files:

                docname, extension = os.path.splitext(fname)

                filename = os.path.join(path,fname)

                file_dict = {}
    
                if extension == ".html":
                    file_dict['type'] = 'circulaire'
                    file_dict['filename'] = fname

                    html_dict = parse_html_to_dict(filename)
                    file_dict.update(html_dict)
                    list_of_dict.append(file_dict)
                
                #elif extension == ".xml":
                #   if not any(d['filename'] == docname for d in list_of_dict):
                #       print("Well Well Well, there's no html file in the list yet !")
                #       continue
                #   else:
                #       index = next((i for i, element in enumerate(list_of_dict) if element['filename'] == docname), None) 
                #       metadata_dict = extract_metadata_xml(filename)
                #       list_of_dict[index].update(metadata_dict)

                else: continue

        json.dump(list_of_dict, outfile, indent=3)

        outfile.close()

############# Extract Metadata from XML FILES #############
import xmltodict

def extract_metadata_xml(filename):
    """ Returns xml file to dict """
    with open(filename, encoding='utf-8', errors='ignore') as xml_file:
        temp_dict = xmltodict.parse(xml_file.read())
        metadata_dict = temp_dict.get('doc', {}).get('fields', {})
    xml_file.close()

    return metadata_dict


通常,我会在 html 文件的 if 循环下方添加一个 elif 条件(现在已注释),它检查 xml 并使用元数据更新相应的字典(文件名相同的布尔条件),因此是顺序的。

但是,不幸的是,对于大多数文件来说,dict 列表似乎不是最新的,或者至少我找不到 40% 的文件名匹配。

我使用的解决方法对我来说似乎有点傻,我在第一个循环之后用 os.walk 编写了第二个循环,专门用于 html 文件,然后我的第二个循环检查 xml 扩展名并附加 list_of_dict,这是完全最新的,我的 html 文件名 100% 与 xml 元数据匹配。

我可以引入一些强制时间以确保在我开始匹配任何 xml 文件名之前完成我的 html 的编写,是否可以为不同的文件并行执行两个 if/elif 循环?

否则,在处理我的 xml 文件之前处理我的所有 html 文件的最佳方式是什么(只是在继续我的 if/elif 循环之前按类型排序我的文件列表?)

我是这个论坛的新手,所以如果我可以改进我的问题写作风格,请告诉我,尽管我正在尽力而为;)。

感谢您的帮助!

【问题讨论】:

  • 如果命名约定和你描述的一样,你应该可以得到xml_filename = os.path.join(path, fname+'.xml')遇到的每个html文件对应的xml文件。在html文件之后打开并处理它并将其存储到同一个循环中的dict中,无需循环两次。
  • NB: else: continue 在循环结束时实际上什么都不做,所以最好删除它。
  • 谢谢,@fsimonjetz,(filename) 和 (fname + '.xml') 是一样的,所以这是我试图应用的方法,仍然在同一个循环中它适用于 60 % 我的文件,但不是其余的。为了完整起见,我现在为我的元数据提取功能添加了代码……如果您在那里看到问题,请 lmk?感谢您的宝贵时间!
  • 不相关的问题,但我使用 get 方法从我的嵌套字典中提取值。但我实际上更愿意在该键没有附加值的情况下引发异常,因此我是否应该在 try/except 语句中使用方括号表示法?更像是:try: metadata_dict = temp_dict['doc']['fields']后跟一个 except 语句来捕获 KeyError 异常?
  • 处理可能丢失的键的最pythonic方法是使用if key in temp_dict:检查键是否存在,然后相应地处理这两种情况。 try/except 实际上仅适用于您无法控制输入的情况,例如捕获用户输入。但是,如果您遵循我在下面的回答中概述的策略,则所有这些都不是必需的。

标签: python html xml dictionary


【解决方案1】:

现在的方式是检查所有文件并以不同方式处理它们,具体取决于它们是 html 还是 xml,希望您遇到的每个 xml 对应的 html 已经被处理——但这不能保证,我怀疑这是是问题的原因。

相反,您应该只查找 html 文件并立即检索相应的 xml:

if extension == ".html":
    file_dict['type'] = 'circulaire'
    file_dict['filename'] = fname
    html_dict = parse_html_to_dict(filename)
    file_dict.update(html_dict)
    
    # process the corresponding xml file

    # this file should always exist, according to your description of the file structure
    xml_filename = os.path.join(path, fname+'.xml')

    # extract the meta data
    metadata_dict = extract_metadata_xml(xml_filename)

    # put it in the file dict we still have
    file_dict.update(metadata_dict)

    # and finally store it
    list_of_dict.append(file_dict)

或者,虽然效率较低,但您也可以遍历 sorted 文件列表 - for fname in sorted(files): - 并照常进行,因为这也会导致 html 文件位于相应的 xml 文件之前.

【讨论】:

  • 谢谢,我会在星期一试一试,如果可行,我会告诉你,但我相信它会的。至于为什么不按顺序进行处理,您能详细说明一下吗?只是试着理解这里的基本原理,如果文件不是按顺序循环而是在我分离 xml 和 html 文件处理 un if/else 语句时是并行的?
  • 当然。问题最终是os 模块以(或多或少)任意顺序列出文件。所以你可能会得到abcde.html.xml 之前 abcde.html。但是如果你只查找*.html文件并手动构建对应的*.xml文件的路径,那么当你添加xml的内容时,可以保证处理好html。
  • 感谢您的解释!根据您的建议,它确实按预期工作!
猜你喜欢
  • 2020-07-29
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 2016-11-18
  • 2018-11-14
相关资源
最近更新 更多