从doc.element.iter()获取docx元素

时间:2018-07-16 15:31:29

标签: python-3.x elements paragraph python-docx

问题:如何使用child对象(如下)实际获取段落或表格对象?

这基于找到的答案here,该答案引用了docx Issue 40

不幸的是,这里发布的所有代码似乎都无法与提交e784a73 一起使用,但是通过检查代码(以及反复试验),我得以接近

我有以下...

def iter_block_items(parent):
    """
    Yield each paragraph and table child within *parent*, in document order.
    Each returned value is an instance of either Table or Paragraph.
    """
    print(type(parent))
    if isinstance(parent, docx.document.Document):
        parent_elm = doc.element.body
    elif isinstance(parent, _Cell):
        parent_elm = parent._tc
    else:
        raise ValueError("something's not right")

    for child in parent_elm.iter():
        if isinstance(child, docx.oxml.text.paragraph.CT_P):
            yield ("(paragraph)", child)
        elif isinstance(child, docx.oxml.table.CT_Tbl):
            yield ("(table)", child)

for i in iter_block_items(doc): 
    print(i)

这成功地遍历了元素,并提供了以下输出...

doc= <class 'docx.document.Document'>
<class 'docx.document.Document'>
('(table)', <CT_Tbl '<w:tbl>' at 0x10c9ce0e8>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9ceef8>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9ce0e8>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9cef98>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9ce0e8>)
('(table)', <CT_Tbl '<w:tbl>' at 0x10c9ceef8>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9cef48>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9cef48>)
('(paragraph)', <CT_P '<w:p>' at 0x10c9cef98>)

这时我需要做的是:每个段落中的文本以及该表的表对象-这样我就可以遍历其单元格。

但是child.text(对于段落)不会返回段落文本(如下面的示例所示),因为child对象实际上不是段落对象,而是应该能够“得到”它。

for para in doc.paragraphs:
    print(para.text)

编辑:

我尝试过:

yield child.text
(yields "None")

from docx.text import paragraph
yield paragraph(child)
(Errors with TypeError: 'module' object is not callable)

from docx.oxml.text import paragraph
yield paragraph(child)
(Errors with TypeError: 'module' object is not callable)

1 个答案:

答案 0 :(得分:1)

如果需要API属性和方法,则需要为每个元素实例化代理对象。那是那些人住的地方。

if isinstance(child, CT_P):
    yield Paragraph(child, parent)
elif isinstance(child, CT_Tbl):
    yield Table(child, parent)

这将生成ParagraphTable对象。 Paragraph对象具有.text属性。对于表,您需要深入到单元格。

代码获得的是底层XML元素对象,该对象使用低级lxml接口(实际上是用所谓的oxml和/或{{1 }}接口),除非您要扩展xmlchemy之类的代理对象的行为,否则它的级别可能要比您想要的低。