尝试使用Python的xml.elementtree将Word docx文件解析为zip文档

时间:2013-12-12 03:48:43

标签: xml python-2.7 elementtree

我正在尝试使用Python的xml.elementtree模块将Windows docx文件解析为zip文件。我将docx文件保存为zip。以下是文档的样子:

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
<?mso-application progid="Word.Document"?>
-<pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage">
-<pkg:part pkg:padding="512" pkg:contentType="application/vnd.openxmlformats-  package.relationships+xml" pkg:name="/_rels/.rels">
+<pkg:xmlData>
</pkg:part>
+<pkg:part pkg:padding="256" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:name="/word/_rels/document.xml.rels">
-<pkg:part pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" pkg:name="/word/document.xml">
-<pkg:xmlData>
-<w:document   xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" mc:Ignorable="w14 wp14">
-<w:body>
-<w:p w:rsidP="00E65A71" w:rsidRDefault="00E65A71" w:rsidR="00E65A71">
-<w:r>
 <w:t>Gloss:</w:t>
 </w:r>
 -<w:r>
 <w:tab/>
 </w:r>
-<w:r w:rsidRPr="00EC6528">
-<w:rPr>
 <w:noProof/>
 </w:rPr>
 <w:t>the door</w:t>
 </w:r>
 </w:p>
-<w:p w:rsidP="00E65A71" w:rsidRDefault="00E65A71" w:rsidR="00E65A71">
-<w:r>
 <w:t xml:space="preserve">Base: </w:t>
 </w:r>
-<w:r>
 <w:tab/>
 </w:r>
-<w:r w:rsidRPr="00EC6528">
-<w:rPr>
 <w:noProof/>
 </w:rPr>
 <w:t>words</w:t>
 </w:r>
-<w:r>

正如您所看到的,我已经将一些元素最小化以节省空间。我对

中的内容感兴趣
<w:document><w:body>

具体要素:

<w:r><w:t>

这就是我要解析的数据。我似乎无法超越第一个元素。以下是试图获得的东西:

import xml.etree.ElementTree as ET
tree = ET.parse('document.xml')
body = tree.getroot().findall("w")
#body = tree.getroot().findall(w:t)
#body = tree.getroot()

还有:

for child in root:
   print child.tag, child.attrib

我试过这只是为了看看我是否可以看到我可以钻进的任何元素但是什么都不返回。我也试过其他代码,但我似乎无法达到我想要的东西。我在Python中编写了很多程序,从未使用过这个模块来解析XML。我正在使用带有pytools的VS studio 2012,当我设置断点并查看“根”结构时,我似乎无法深入到我想要的元素中。我似乎无法浏览“pkg:package”的东西。我的最终目标是设置一个for循环来处理将在整个文档中重复的“”内容。我已经研究了一段时间,并尝试通过一些教程,所以任何帮助都非常感谢!感谢。

1 个答案:

答案 0 :(得分:3)

在Open Office Xml(Microsoft为其较新的Office软件使用的标准)中,标记中冒号前面的字母是前缀,需要正确处理特定的命名空间映射。例如,标签&lt; w:t&gt;实际上要求您搜索标记字符串“{http://schemas.openxmlformats.org/wordprocessingml/2006/main} t”。前缀/命名空间用大括号括起来,实际的标记名称在末尾。幸运的是,您可能正在寻找的大部分内容都使用了我上面提到的命名空间。这里有一些示例代码可以让您从正确的方向开始:

import xml.etree.ElementTree as ET

# I find that using a dictionary to map prefixes to namespaces keeps
# things easier to understand. You can also use the namespaces directly
# though if you prefer
NAMESPACE_PREFIXES = {
    'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'
    }  

tree = ET.parse('document.xml')
root = tree.getroot()
text_elements = [element for element in root.iter() if element.tag == 
'{' + NAMESPACE_PREFIXES['w'] + '}t']
# Equivalent to:
# text_elements = [element for element in root.iter() if element.tag == 
# '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t']
for text_element in text_elements:
    if text_element.text == 'Hello world!':
        text_element.text = 'Goodbye world!'

Here是OOXML的一些额外命名空间,以防您需要它们。