问题:如何使用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)
答案 0 :(得分:1)
如果需要API属性和方法,则需要为每个元素实例化代理对象。那是那些人住的地方。
if isinstance(child, CT_P):
yield Paragraph(child, parent)
elif isinstance(child, CT_Tbl):
yield Table(child, parent)
这将生成Paragraph
和Table
对象。 Paragraph
对象具有.text
属性。对于表,您需要深入到单元格。
代码获得的是底层XML元素对象,该对象使用低级lxml
接口(实际上是用所谓的oxml
和/或{{1 }}接口),除非您要扩展xmlchemy
之类的代理对象的行为,否则它的级别可能要比您想要的低。