如何解决使用Python从法语的Word文档中提取XML的问题:生成了非法字符
问题是,你不小心改变的编码word/document.xml
在template2.docx
。word/document.xml
(来自template.docx
)最初被编码为UTF-8(这是XML文档的默认编码)。
xmlString = zip.read("word/document.xml").decode("utf-8")
但是,当您复制它时,会将template2.docx
编码更改为 CP-1252 。根据有关的文档open(file,
"w")
,
在文本模式下,如果未指定编码,则使用的编码取决于平台:调用locale.getpreferredencoding(False)以获取当前的语言环境编码。
您指示调用locale.getpreferredencoding(False)
给您正在编写cp1252
的编码word/document.xml
。
由于您没有显式添加<?xml version="1.0"
encoding="cp1252"?>
到的开头word/document.xml
,因此Word(或任何其他XML读取器)会将其读取为 UTF-8
而不是 CP-1252 ,这将导致出现非法的XML字符错误。
因此,您要在写入时通过使用参数指定为 UTF-8 的编码:encoding``open()
with open(os.path.join(tmpDir, "word/document.xml"), "w", encoding="UTF-8") as f:
f.write(xmlString)
解决方法
在过去的几天中,我一直在尝试创建一个脚本,该脚本将1)从Word文档中提取XML,2)修改XML,以及3)使用新XML创建并保存新的Word文档。在许多用户的帮助下,我最终能够找到看起来很有希望的代码。这里是:
import zipfile
import os
import tempfile
import shutil
def getXml(docxFilename):
zip = zipfile.ZipFile(open(docxFilename,"rb"))
xmlString= zip.read("word/document.xml").decode("utf-8")
return xmlString
def createNewDocx(originalDocx,xmlString,newFilename):
tmpDir = tempfile.mkdtemp()
zip = zipfile.ZipFile(open(originalDocx,"rb"))
zip.extractall(tmpDir)
with open(os.path.join(tmpDir,"word/document.xml"),"w") as f:
f.write(xmlString)
filenames = zip.namelist()
zipCopyFilename = newFilename
with zipfile.ZipFile(zipCopyFilename,"w") as docx:
for filename in filenames:
docx.write(os.path.join(tmpDir,filename),filename)
shutil.rmtree(tmpDir)
getXml
从中提取XMLdocxFilename
作为字符串。createNewDocx
接收原始Word文档,并将其XML替换为xmlString
,这是原始XML的修改版本,并将生成的Word文档另存为newFilename
。
为了检查脚本是否按预期工作,我首先创建了一个测试文档(“
test.docx”)并运行了createNewDocx("test.docx",getXml("test.docx"),"test2.docx")
。如果一切都按预期工作,则应该创建一个保存为test2.docx的相同test.docx副本。确实是这样。
然后,我对测试文档进行了更详尽的阐述,并尝试对其进行修改。而且脚本仍然有效!
然后,我自信地将脚本应用于了我实际上对修改感兴趣的Word文档template.docx
。我运行createNewDocx("template.docx",getXml("template.docx"),"template2.docx")
,期望脚本将生成template.docx的相同副本,但名为template2.docx。不幸的是,新的Word文档无法打开。显然,XML中存在非法字符。
我真的不明白为什么我的代码对我的测试文档有效,而不对我的实际文档有效。我会发布template.docx的XML,但其中包含个人信息。test.docx和template.docx之间的一个重要区别是template.docx是用法语编写的,因此包含诸如重音符号的特殊字符,并且撇号看起来也有所不同。我不知道这是否是造成我麻烦的原因,但我没有其他想法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。