使用pythondocx在docx中迭代目录

使用pythondocx在docx中迭代目录,python,python-docx,Python,Python Docx,我有一个文档,它的目录是在文档的开头自动生成的,我想通过这个目录进行解析。使用python docx是否可以做到这一点?如果我尝试遍历文档段落.text,则目录中的文本不会显示 我尝试了以下方法:迭代段落,检查段落.style.name是否为toc1,然后我知道我在toc中。但我无法得到实际的文本。我试过这个: if para.style.name == "toc 1" #then print para.text. 但是para.text给了我一个空白字符串。为什么会这样 谢谢我相信您会发现

我有一个文档,它的目录是在文档的开头自动生成的,我想通过这个目录进行解析。使用python docx是否可以做到这一点?如果我尝试遍历
文档段落.text
,则目录中的文本不会显示

我尝试了以下方法:迭代段落,检查
段落.style.name
是否为
toc1
,然后我知道我在toc中。但我无法得到实际的文本。我试过这个:

if para.style.name == "toc 1" #then print para.text. 
但是
para.text
给了我一个空白字符串。为什么会这样


谢谢

我相信您会发现TOC的实际生成内容被“包装”在一个非段落元素中
PythonDocx
不会直接到达那里,因为它只查找
w:document/w:body
元素的直接子元素的段落

要达到这些目标,您需要进入lxml级别,使用pythondocx使您尽可能接近lxml。您可以使用以下命令访问(并打印)body元素:

document = Document('my-doc.docx')
body_element = document._body._body
print(body_element.xml)  # this will be big if your document is
从那里,您可以识别所需部件的特定XML位置,并使用lxml/XPath访问它们。然后,您可以将它们包装在python docx
段落
对象中,以便随时访问:

from docx.text.paragraph import Paragraph

ps = body_element.xpath('./w:something/w:something_child/w:p'
paragraphs = [Paragraph(p, None) for p in ps]
这不是一个精确的配方,需要您进行一些研究,以确定什么是
w:something
等,但如果您希望它足够糟糕,以克服这些障碍,这种方法将起作用


一旦你让它工作起来,发布你的确切解决方案可能会对其他人的搜索有所帮助。

我相信你会发现TOC的实际生成内容被“包装”在一个非段落元素中
PythonDocx
不会直接到达那里,因为它只查找
w:document/w:body
元素的直接子元素的段落

要达到这些目标,您需要进入lxml级别,使用pythondocx使您尽可能接近lxml。您可以使用以下命令访问(并打印)body元素:

document = Document('my-doc.docx')
body_element = document._body._body
print(body_element.xml)  # this will be big if your document is
从那里,您可以识别所需部件的特定XML位置,并使用lxml/XPath访问它们。然后,您可以将它们包装在python docx
段落
对象中,以便随时访问:

from docx.text.paragraph import Paragraph

ps = body_element.xpath('./w:something/w:something_child/w:p'
paragraphs = [Paragraph(p, None) for p in ps]
这不是一个精确的配方,需要您进行一些研究,以确定什么是
w:something
等,但如果您希望它足够糟糕,以克服这些障碍,这种方法将起作用


一旦你成功了,发布你的准确答案可能会对其他人的搜索有所帮助。

由于大部分答案都隐藏在评论部分,我花了一段时间才弄清楚OP到底做了什么,以及scanny的答案如何改变了他所做的,我将在这里发布我的答案,这只是斯坎尼回答中评论部分的内容。我不完全理解代码是如何工作的,所以如果有人想编辑我的答案,请随意编辑

#open docx file with python-docx
document = docx.Document("path\to\file.docx")
#extract body elements
body_elements = document._body._body
#extract those wrapped in <w:r> tag
rs = body_elements.xpath('.//w:r')
#check if style is hyperlink (toc)
table_of_content = [r.text for r in rs if r.style == "Hyperlink"]
#使用python docx打开docx文件
document=docx.document(“path\to\file.docx”)
#提取身体元素
正文\元素=文档。\正文。\正文
#取出那些包裹在标签里的东西
rs=body_elements.xpath('.//w:r')
#检查样式是否为超链接(toc)
表_of_content=[r.text for r in rs if r.style==“Hyperlink”]

_内容的表_将是一个列表,首先包括作为项目的编号,然后是标题

由于大部分解决方案都隐藏在评论部分,我花了一段时间才弄清楚OP到底做了什么,以及scanny的回答如何改变了他正在做的事情,所以我将在这里发布我的解决方案,这只是scanny回答的评论部分写的内容。我不完全理解代码是如何工作的,所以如果有人想编辑我的答案,请随意编辑

#open docx file with python-docx
document = docx.Document("path\to\file.docx")
#extract body elements
body_elements = document._body._body
#extract those wrapped in <w:r> tag
rs = body_elements.xpath('.//w:r')
#check if style is hyperlink (toc)
table_of_content = [r.text for r in rs if r.style == "Hyperlink"]
#使用python docx打开docx文件
document=docx.document(“path\to\file.docx”)
#提取身体元素
正文\元素=文档。\正文。\正文
#取出那些包裹在标签里的东西
rs=body_elements.xpath('.//w:r')
#检查样式是否为超链接(toc)
表_of_content=[r.text for r in rs if r.style==“Hyperlink”]

_内容的表_将是一个列表,首先包括作为项目的编号,然后是标题

我开始尝试使用您的提示,但当我看到xml文件时,我只看到部分的名称,而不是编号。例如,如果目录中有一个条目:2.3.4 Intro…….5,我看到的是“Intro”,而不是2.3.4。你知道为什么会这样吗?我真的想要号码和文字。(这是一个自动生成的ToC,不确定这是否有区别。)ThanksI必须查看整个ToC XML块,也许您可以将其发布在要点或其他内容中。但是我希望Word是基于样式或编号属性来计算这些数字的,并且不会将它们记录在XML中以避免冗余(因此需要保持两者同步)。位于:。例如,如果你看“简介”部分,我想看“1简介”等。谢谢你的帮助!好的,是的,我看到节号(如1.3.1)实际上在那里,就在前面的一次运行中,由一个制表符和其他位分隔。在您注册的XML中,没有“container”元素,这意味着这些段落应该出现在Document.parations中。然后,您可以对以“TOC”开头的样式进行筛选,然后对所需文本的运行进行排序。我希望你能在每个段落的相同运行索引中找到数字和标题之类的内容,比如段落运行[0],段落运行[2]。让我们知道你进展如何:)如果答案对你有用,别忘了投赞成票,如果答案正确,请接受。啊,有趣的是,跑步记录被包装在一个w:hyperlink中。所以您需要这样做:rs=段落。_p.xpath('.//w:r');对于rs:print(Run(r,段落).text)中的r,我开始尝试使用您的提示,但是当我看到xml文件时,我只看到了