无法从 docx 中提取元素 xpath

问题描述 投票:0回答:1

使用 python-docx-oss,我使用以下代码(我想将标题 3 样式写入 TXT 文件,并仅包含第 3 级编号的大纲/级别,即 x.x.x):

from docx import Document
from docx.oxml.ns import qn

def docx_to_txt(input_path, output_path):
    doc = Document(input_path)
    output_lines = []
    capture_heading_3_content = False

    def is_heading_3(paragraph):
        # Check if the paragraph is Heading 3 (Outline level 3 in Word)
        if paragraph.style.name == 'Heading 3':
            outline_lvl = paragraph._element.xpath('.//w:pPr/w:pStyle/w:numPr/w:ilvl/@w:val', namespaces={'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'})            
            print(outline_lvl)
            return outline_lvl and outline_lvl[0] == '2'  # Outline level 3 is represented by '2' in Word
        return False

    for element in doc.element.body:
        if element.tag.endswith('p'):  # Paragraph
            para = next(p for p in doc.paragraphs if p._element == element)
            if is_heading_3(para):
                capture_heading_3_content = True
                output_lines.append(para.text + '\n')
            elif capture_heading_3_content:
                output_lines.append('TEXT')

    # Write to output file
    with open(output_path, 'w', encoding='utf-8') as f:
        for line in output_lines:
            if line.strip():  # To avoid writing empty lines
                f.write(line)

input_docx = 'demo.docx'
output_txt = 'demo.txt'
docx_to_txt(input_docx, output_txt)

我可以使用

提取标题3的样式
paragraph._element.xpath('.//w:pPr/w:pStyle/@w:val', 

但是

paragraph._element.xpath('.//w:pPr/w:pStyle/w:numPr/w:ilvl/@w:val', 

不起作用(当用outlineLvl替换ilvl时也是如此)

document.xml(从 docx zip 中提取)如下:

space="preserve"> </w:t></w:r></w:p><w:p w14:paraId="51F57A9F" 
w14:textId="77777777" w:rsidR="00B23BA1" w:rsidRPr="00107F54" 
w:rsidRDefault="00B23BA1" w:rsidP="00B23BA1"><w:r 
w:rsidRPr="00107F54"><w:t>In the next paragraphs, ...</w:t></w:r></
w:p><w:p w14:paraId="47ED129E" w14:textId="60ED4712" w:rsidR="00E81AC6"
 w:rsidRPr="00E81AC6" w:rsidRDefault="00E81AC6" 
w:rsidP="00B23BA1">
<w:pPr><w:pStyle w:val="Heading3"/><w:numPr><w:ilvl w:val="2"/><w:numId w:val="5"/></w:numPr></w:pPr>
<w:bookmarkStart 
w:id="140" w:name="_Toc166773442"/><w:r w:rsidRPr="00E81AC6"><w:t>Increased risk</w:t></w:r><w:bookmarkEnd 
w:id="140"/></w:p><w:tbl><w:tblPr><w:tblStyle w:val="TableGrid"/
><w:tblW w:w="0" w:type="auto"/><w:tblLook w:val="04A0" w:firstRow="1"
 w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" 
w:noVBand="1"/><w:tblCaption w:val="Finding"/
><w:tblDescription w:val="Vulnerability identifier."/></w:tblPr><w:tblGrid><w:gridCol 
w:w="2547"/><w:gridCol w:w="6469"/></w:tblGrid><w:tr w:rsidR="00E81AC6"
 w:rsidRPr="00E8

为什么我取不到2的ilvl值?

谢谢你,

python xpath lxml python-docx
1个回答
0
投票

pStyle
numPr
的兄弟姐妹,而不是父级。 xpath 应该是

.//w:pPr/w:numPr/w:ilvl/@w:val

<w:pPr>
  <w:pStyle w:val="Heading3"/>
  <w:numPr>
    <w:ilvl w:val="2"/>
    <w:numId w:val="5"/>
  </w:numPr>
</w:pPr>
© www.soinside.com 2019 - 2024. All rights reserved.