尝试将MSWord 2007文档转换为XML格式
我希望能省略一些背景,但请相信我接下来的内容:
- 我有好几个人可以直接使用MSWord 2007。
- 我们想准备一个通用的Word文档,这个文档可以在几个月内由不同的人传递,他们可以在上面“添加”新内容。
无论下面的回答是什么,上面的情况都不会改变,不管这个主意有多糟糕,或者你有什么更好的想法……我已经走过这条路了 :P。
- 我想在Word里设置一个XML模式,这样我们就可以为特定内容区域“标记”内容(比如:项目编号、项目描述、项目主体、项目选项、项目答案等等)。
- 我自学了XML模式,花了不到6个小时,结果发现我教得很糟糕:我有XML模式文件,已经把它导入到Word里,能够按照网上的教程标记区域……
- 我希望能从Word保存为一个“XML”文件,格式看起来像这样:
<note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note>
(这个是我从一个随机网站上找的,目的是为了展示我想从Word文档中保存XML结构和填充的数据)
我的希望是,之后我可以用Python解析这个文件,或者把XML文件发给一个供应商,让他们把信息上传到数据库(而且——我们不能直接上传到数据库——必须是从Word文档到XML再到供应商)。
问题是:每次我从MSWord 2007保存文件为XML时,得到的都是一堆糟糕的XML内容——我检查过,发现我的XML标签确实在里面,但被Office的标签弄得一团糟,解析出来简直是浪费时间。
最后:我怎么才能让Word自动填充XML标签(我明白“自动”是指需要有人“选择文本”、“分配XML”……我更想知道的是关于‘保存’为XML的过程)?我可以从我开发的模式中导出内容,准备好上传/解析吗?(或者我可以不使用模式直接创建一个示例XML树吗?)
谢谢你读完我的短篇小说 :P(希望我说得够清楚!)
-J
1 个回答
如果你的数据和你提供的例子一样简单(也就是说,只有 note
元素,并且字段数量是固定的),那么你可以在Word文档里做一个大表格,里面有 to
、from
、heading
、body
等列。然后,你可以用Python中的某种方法来解析这个表格,生成你需要的自定义XML。因为 .docx
文件本身就是XML格式的,这可能会让你的工作变得简单一些,也可能不会。
如果数据比较复杂,一个想法是使用Word的样式来把文本映射到正确的标签上。你可以为每个标签创建一个自定义样式,这样用户只需简单点击一下(并且可以设置不同的颜色和/或字体)。然后在解析文档时,你可以根据段落的样式来过滤内容。不过,我觉得这样做可能会比较麻烦。
另一个选择是用一种结构化的语法来写文档,比如 YAML,这种格式手动读写都很简单,你可以直接把文件保存为纯文本来解析,比如:
# plaintext_export.txt
------------------
Notes:
- From: Somebody
To: Somebody-else
Heading: This is a heading
Message: >
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
- From: Another guy
To: Me
Heading: Huh?
Message: >
Some other message content.
解析的过程会简单得多:
>>> import yaml
>>> from pprint import pprint
>>> with open("plaintext_export.txt", 'r') as f:
... data = yaml.load(f)
...
>>> pprint(data)
{'Notes': [{'From': 'Somebody',
'Heading': 'This is a heading',
'Message': 'Lorem ipsum dolor sit amet, consectetur adipisicing elit
, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. \n',
'To': 'Somebody-else'},
{'From': 'Another guy',
'Heading': 'Huh?',
'Message': 'Some other message content.\n',
'To': 'Me'}]}