后端【免费下载链接】python-docxCreate and modify Word documents with Python项目地址https://gitcode.com/gh_mirrors/py/python-docx点击查看免费下载CT_Document是 python-docx 中对 WordprocessingML 主文档部件document.xml根元素w:document的 XML 类型定义它规定了整个文档正文树的结构与约束。本文以 docs/dev/analysis/schema/ct_document.rst 为骨架结合仓库内的 XSD 规范wml.xsd、源码实现src/docx/oxml/document.py与测试用例逐层剖析CT_Document、CT_Body、CT_Background的 Schema 结构、conformance属性语义以及 python-docx 如何将这份规范转化为可编程的 Python 类。读完本文你将掌握w:document元素的内容模型、节section机制的实现原理以及库内文档操作 API 与底层 XML 元素之间的调用链。一、CT_Document 是什么主文档部件的根元素在 OOXMLOffice Open XML的 WordprocessingML 命名空间下.docx文件包中真正承载正文内容的部件是主文档部件main document part其内部 XML 文件的根元素就是w:document。ISO/IEC 29500 规范第 17.2.3 节对它的定义是This element specifies the contents of a main document part in a WordprocessingML document.也就是说w:document描述了主文档部件的全部内容文档正文的所有内容都嵌套在该元素之下。一个最基本的 WordprocessingML 主文档结构如下w:document w:body w:p/ /w:body /w:document其中w:body是文档正文的容器w:p是最小的块级元素——段落。三者的层级关系构成了一张从文档根到内容的树层级元素角色根w:document主文档部件根元素含w:background与w:body正文w:body文档正文编辑面承载所有块级内容与尾部节属性块级w:p/w:tbl/w:sdt...段落、表格等正文内容单元同一主题的姐妹文档 docs/dev/analysis/schema/ct_body.rst 对w:body给出了更细的说明它指定的是文档正文——主文档编辑面的内容其子元素被称为块级标记block-level markup即可以作为段落兄弟节点出现的标记。一个元素之所以属于主文档故事main document story正是因为它位于w:body内部。二、Schema 层面的类型定义CT_Document 与 CT_Background2.1 CT_Document 的内容模型根据 wml.xsd 中与 docs/dev/analysis/schema/ct_document.rst 一致的定义CT_Document是一个 complexType其结构可概括为xsd:complexType nameCT_Document xsd:sequence xsd:element namebackground typeCT_Background minOccurs0/ xsd:element namebody typeCT_Body minOccurs0 maxOccurs1/ /xsd:sequence xsd:attribute nameconformance types:ST_ConformanceClass/ /xsd:complexType解读这份定义可以得出三个关键约束子元素顺序w:background必须出现在w:body之前xsd:sequence保证有序性。出现次数w:background可选minOccurs0w:body同样可选且最多一次minOccurs0 maxOccurs1。虽然 Schema 允许两者都缺失但一个合法的主文档部件必然包含w:body承载内容。属性conformance属性控制文档的符合性类别。2.2 conformance 属性与 ST_ConformanceClassconformance属性由s:ST_ConformanceClass简单类型约束枚举值只有两个xsd:simpleType nameST_ConformanceClass xsd:restriction basexsd:string xsd:enumeration valuestrict/ xsd:enumeration valuetransitional/ /xsd:restriction /xsd:simpleTypestrict声明文档严格符合 ISO/IEC 29500 Strict 版本即禁止使用任何 Transitional 特性。transitional允许使用过渡期兼容特性默认情况。该属性在 python-docx 生成的默认文档中并未显式出现见下文第四节说明缺省时即视为 transitional。2.3 CT_Background文档级背景定义w:background用于指定文档级背景注意它位于w:body之前作用于整个文档而非某个节。其 XSD 定义展现了 WordprocessingML 对 VML/Office 命名空间元素的宽容处理xsd:complexType nameCT_Background xsd:sequence xsd:sequence maxOccursunbounded xsd:any processContentslax namespaceurn:schemas-microsoft-com:vml minOccurs0 maxOccursunbounded/ xsd:any processContentslax namespaceurn:schemas-microsoft-com:office:office minOccurs0 maxOccursunbounded/ /xsd:sequence xsd:element namedrawing typeCT_Drawing minOccurs0/ /xsd:sequence xsd:attribute namecolor typeST_HexColor useoptional/ xsd:attribute namethemeColor typeST_ThemeColor useoptional/ xsd:attribute namethemeTint typeST_UcharHexNumber useoptional/ xsd:attribute namethemeShade typeST_UcharHexNumber useoptional/ /xsd:complexType要点如下允许零个或多个来自 VMLurn:schemas-microsoft-com:vml与 Officeurn:schemas-microsoft-com:office:office命名空间的任意元素采用processContentslax——即校验器对已知类型做校验、对未知内容放行这一设计为兼容旧版 Word 生成的背景标记留出了余地。可选的w:drawing子元素用于承载 DrawingML 图形。四个可选属性共同控制背景外观color十六进制颜色值ST_HexColor如auto或FF0000themeColor主题色引用ST_ThemeColorthemeTint/themeShade对主题色的着色/阴影微调ST_UcharHexNumber即十六进制无符号数。从 python-docx 的源码来看CT_Background并未被映射为独立的自定义元素类src/docx/oxml/init.py 中只注册了w:document、w:body等类意味着该元素由通用 lxml 元素处理、保持原样传递这符合规范中lax 校验的宽容精神。三、CT_Body块级内容的选择器与节属性w:body的类型CT_Body是正文内容模型的真正核心。它的主体是一个minOccurs0 maxOccursunbounded的xsd:choice允许正文中按任意顺序、任意次数出现下列元素部分列举元素类型用途w:pCT_P段落w:tblCT_Tbl表格w:sdtCT_SdtBlock结构化文档标签w:customXmlCT_CustomXmlBlock自定义 XML 块w:altChunkCT_AltChunk外部内容引用HTML 导入等w:proofErr/w:permStart/w:permEnd各类标记拼写检查、编辑权限范围标记w:bookmarkStart/w:bookmarkEndCT_Bookmark/CT_MarkupRange书签范围w:commentRangeStart/w:commentRangeEndCT_MarkupRange批注引用范围w:ins/w:del/w:moveFrom/w:moveToCT_RunTrackChange修订插入、删除、移动m:oMathPara/m:oMath数学命名空间元素OMML 数学公式在xsd:choice之后CT_Body声明了一个可选的收尾元素xsd:element namesectPr minOccurs0 maxOccurs1 typeCT_SectPr/这个body 尾部的w:sectPr节属性哨兵是理解 python-docx 节机制的关键它描述了文档最后一个节的页面设置页边距、纸张尺寸、页眉页脚引用等。而正文中每个段落w:p/w:pPr/w:sectPr若携带w:sectPr则代表该段落结束处开启一个新的节。因此文档中节的划分可以这样概括除最后一个节由w:body直接子级的w:sectPr描述外其余每个节都由正文内某个段落属性中的w:sectPr终结。四、python-docx 的实现映射从 XSD 到 Python 类4.1 自定义元素类的声明式定义python-docx 用 src/docx/oxml/xmlchemy.py 中的ZeroOrOne、ZeroOrMore、OneAndOnlyOne等描述符把 XSD 约束翻译成 Python 类属性。以CT_Document为例src/docx/oxml/document.pyclass CT_Document(BaseOxmlElement): w:document element, the root element of a document.xml file. body: CT_Body ZeroOrOne(w:body)声明body: CT_Body ZeroOrOne(w:body)会经由元类MetaOxmlElementsrc/docx/oxml/xmlchemy.py自动为类注入body属性访问器、add_body()创建方法、_insert_body()插入方法等配套方法。这与 XSD 中w:body的minOccurs0 maxOccurs1完全对应——零个或一个。CT_Body的声明则对应其任意个块级元素 至多一个收尾 sectPr的内容模型class CT_Body(BaseOxmlElement): p ZeroOrMore(w:p, successors(w:sectPr,)) tbl ZeroOrMore(w:tbl, successors(w:sectPr,)) sectPr: CT_SectPr | None ZeroOrOne(w:sectPr, successors())successors(w:sectPr,)参数保证新增的w:p、w:tbl始终插入在正文末尾的w:sectPr之前从而维持块级内容在前、节属性收尾的合法顺序。4.2 类注册与解析器挂钩这些自定义类通过 src/docx/oxml/init.py 中的register_element_cls注册到 lxml 的自定义元素类查找表from .document import CT_Body, CT_Document register_element_cls(w:body, CT_Body) register_element_cls(w:document, CT_Document)注册机制实现在 src/docx/oxml/parser.pyregister_element_cls将w:document拆成前缀与标签名把类挂到对应命名空间下随后parse_xml()使用配置了ElementNamespaceClassLookup的oxml_parser解析 XML 时遇到w:document标签就会自动构造CT_Document实例。由此库内部任何对文档 XML 的访问都表现为强类型的 Python 对象操作。4.3 默认文档模板中的真实 XMLpython-docx 的内置空白文档模板 src/docx/templates/default-docx-template/word/document.xml 展示了w:document在真实文件中的形态命名空间已精简w:document ... xmlns:whttp://schemas.openxmlformats.org/wordprocessingml/2006/main xmlns:rhttp://schemas.openxmlformats.org/officeDocument/2006/relationships ... w:body w:sectPr w:rsidR00FC693F w:rsidRPr0006063C w:rsidSect00034616 w:pgSz w:w12240 w:h15840/ w:pgMar w:top1440 w:right1800 w:bottom1440 w:left1800 w:header720 w:footer720 w:gutter0/ w:cols w:space720/ w:docGrid w:linePitch360/ /w:sectPr /w:body /w:document这份默认模板恰好验证了上文两个论断根元素即为w:document其下直接是w:body没有w:background该元素本就可选空文档的w:body内没有任何块级内容只有尾部w:sectPr定义默认节A4/Letter 尺寸w:pgSz12240×15840 twips、页边距上下 1440、左右 1800 twips等。这也解释了CT_Document的body为何用ZeroOrOne——刚创建的空文档确实只有w:body而没有段落。当调用 src/docx/api.py 的Document()且不传参数时库会加载这份默认模板作为新文档起点def Document(docxNone): docx _default_docx_path() if docx is None else docx document_part cast(DocumentPart, Package.open(docx).main_document_part) if document_part.content_type ! CT.WML_DOCUMENT_MAIN: raise ValueError(...) return document_part.document五、源码级的核心操作sectPr_lst 与节遍历CT_Document上最值得研究的方法是由源码自定义的sectPr_lst属性src/docx/oxml/document.py它用一条 XPath 汇总了文档中所有可见的节属性元素property def sectPr_lst(self) - List[CT_SectPr]: xpath ./w:body/w:p/w:pPr/w:sectPr | ./w:body/w:sectPr return self.xpath(xpath)该表达式匹配两类w:sectPr./w:body/w:p/w:pPr/w:sectPr——正文中段落属性内的节属性非末节./w:body/w:sectPr——正文尾部的哨兵节属性末节。两条路径取并集、按文档顺序返回因此最后一个元素恒为w:body/w:sectPr。注意源码注释特别提醒被修订标记如w:ins或w:sdt、w:customXml等包裹层遮蔽的段落节属性不会被统计。Sections集合src/docx/section.py正是建立在这个属性之上的代理层class Sections(Sequence[Section]): def __init__(self, document_elm: CT_Document, document_part: DocumentPart): self._document_elm document_elm ... def __getitem__(self, key): return Section(self._document_elm.sectPr_lst[key], self._document_part) def __iter__(self): for sectPr in self._document_elm.sectPr_lst: yield Section(sectPr, self._document_part) def __len__(self): return len(self._document_elm.sectPr_lst)于是用户可以通过document.sections以序列方式访问、遍历、切片文档的所有节每个Section对象再暴露top_margin、bottom_margin、different_first_page_header_footer等页面设置属性src/docx/section.py。整个调用链可表示为Document.sections → Sections.__iter__ / __getitem__ / __len__ → CT_Document.sectPr_lst (XPath) → w:body/w:p/w:pPr/w:sectPr 与 w:body/w:sectPr 的 CT_SectPr 实例六、CT_Body 的三个实用操作及测试验证CT_Body提供了三个对文档编程至关重要的方法src/docx/oxml/document.py。6.1 clear_content()清空正文def clear_content(self): Remove all content child elements from this w:body element. Leave the w:sectPr element if it is present. for content_elm in self.xpath(./*[not(self::w:sectPr)]): self.remove(content_elm)它删除w:body中除w:sectPr外的所有子元素。测试用例tests/oxml/parts/test_document.py通过参数化 fixture 验证了五种场景空 body、仅有w:p、仅有w:tbl、仅有w:sectPr、w:pw:sectPr并存——结论是w:sectPr始终被保留正文内容则被清空。这一行为也被 tests/test_document.py 的上层测试覆盖。6.2 add_section_break()追加节def add_section_break(self) - CT_SectPr: sentinel_sectPr self.get_or_add_sectPr() self.add_p().set_sectPr(sentinel_sectPr.clone()) for hdrftr_ref in sentinel_sectPr.xpath(w:headerReference|w:footerReference): sentinel_sectPr.remove(hdrftr_ref) return sentinel_sectPr其算法完全对应本文第三节描述的节由段落内的w:sectPr终结模型取出正文尾部的哨兵w:sectPr克隆一份并挂到新增段落w:p/w:pPr/w:sectPr上——原末节变成倒数第二节从哨兵中删除所有页眉页脚引用使新末节继承前一节的页眉页脚返回哨兵作为新文档末节的属性元素。对应测试tests/oxml/parts/test_document.py断言对w:body/w:sectPr/w:type{w:valfoobar}调用后XML 变为w:body/(w:p/w:pPr/w:sectPr/w:type{w:valfoobar},w:sectPr/w:type{w:valfoobar})——即新增的段落节属性与原哨兵各持有一份相同的w:type内容。6.3 inner_content_elements按文档序取块级内容property def inner_content_elements(self) - List[CT_P | CT_Tbl]: return self.xpath(./w:p | ./w:tbl)它按文档顺序返回w:body直属的w:p与w:tbl。测试tests/oxml/test_document.py验证了对w:body/(w:tbl, w:p, w:p)会返回[CT_Tbl, CT_P, CT_P]。这一属性是块级容器代理的基石BlockItemContainersrc/docx/blkcntnr.py的iter_inner_content()正是遍历它再把CT_P包装成Paragraph、把CT_Tbl包装成Table返回从而实现document.paragraphs、document.tables与iter_inner_content()等 API。七、与用户 API 的衔接add_paragraph 与 add_table 的底层路径w:body上声明的p ZeroOrMore(...)、tbl ZeroOrMore(...)会在类上生成add_p()、add_tbl()等创建方法它们是高层 API 的落点Document.add_paragraph()src/docx/document.py→self._body.add_paragraph(...)→BlockItemContainer._add_paragraph()src/docx/blkcntnr.py→self._element.add_p()即向w:body追加一个w:pDocument.add_table()→BlockItemContainer.add_table()src/docx/blkcntnr.py→CT_Tbl.new_tbl(rows, cols, width)构造表格元素再经self._element._insert_tbl(tbl)插入正文。由于ZeroOrMore声明了successors(w:sectPr,)这些插入操作都会自动维护块级内容在w:sectPr之前的正确顺序用户无需关心底层元素排列。这正是 XSD 内容模型在实现层面的直接体现Schema 约束被描述符转化为插入顺序保障。八、阅读指引与延伸材料围绕CT_Document主题仓库内值得继续研读的材料包括规范分析文档docs/dev/analysis/schema/ct_body.rstw:body与CT_SectPr的完整 XSD 与规范原文、docs/dev/analysis/schema/ct_p.rst段落元素CT_PXSD 规范源文件wml.xsdWordprocessingML 全部 complexType 定义与 dml-wordprocessingDrawing.xsd内联图形类型核心实现src/docx/oxml/document.pyCT_Document/CT_Body、src/docx/oxml/xmlchemy.py描述符机制、src/docx/oxml/parser.py元素类注册与解析上层封装src/docx/document.pyDocument代理对象、src/docx/section.pySection/Sections、src/docx/blkcntnr.py块级容器测试佐证tests/oxml/test_document.pyinner_content_elements、tests/oxml/parts/test_document.pyclear_content与add_section_break。理解CT_Document相当于拿到了阅读 python-docx 源码与 OOXML 文档结构的第一把钥匙从根元素的内容模型出发向上可以把握Document、Sections、BlockItemContainer等 API 的设计动机向下可以追溯每次文档操作最终落到了哪个 XML 元素上。赞分享后端【免费下载链接】python-docxCreate and modify Word documents with Python项目地址https://gitcode.com/gh_mirrors/py/python-docx点击查看免费下载相关推荐python-docx 运行级内容Run-level Content深入解析w:r 内部元素的 Schema、文本语义与编程接口python docx 运行级内容Run level Content深入解析 w:r 内部元素的 Schema、文本语义与编程接口 本文档导读 本文以后端DrissionPage框架中处理iframe元素的技术解析DrissionPage框架中处理iframe元素的技术解析 引言 在Web自动化测试和爬虫开发中iframe元素一直是开发者需要面对的特殊场景。传统的Sel网页爬虫浏览器控制测试RPAAwesome Public Datasets架构解析自动化生成系统的技术内幕Awesome Public Datasets架构解析自动化生成系统的技术内幕 引言数据聚合的自动化革命 在数据驱动的时代高质量公共数据集的发现和整理成为文档知识库数据集上一篇Node.js 25.4.0Current发布深度解读CLI 新选项、模块系统稳定化与下载校验全指南下一篇Tock 在 Verilated LiteX SoC 仿真平台上的运行指南构建、加载应用与调试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?