【发布时间】: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