docx_plus.core.oxml¶
Element-construction and XPath helpers. All XML construction in the
library goes through these — see ARCHITECTURE.md §8,
invariant 2.
docx_plus.core.oxml ¶
Element-construction helpers — the single chokepoint for OOXML I/O.
Capability modules must construct elements through :func:el and :func:sub
rather than calling lxml.etree directly. SPEC §9.2.
el ¶
Create a namespaced element with attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
tag
|
str
|
Element name in |
required |
**attrs
|
str
|
Attributes. Keys may be namespaced ( |
{}
|
Returns:
| Type | Description |
|---|---|
_Element
|
A fresh detached :class: |
Example
style = el("w:style", **{"w:type": "paragraph", "w:styleId": "Foo"}) style.tag.endswith("}style") True
Source code in docx_plus/core/oxml.py
sub ¶
Create a namespaced child of parent and append it.
Equivalent to :func:el followed by parent.append(...). Returned for
chained use.
Source code in docx_plus/core/oxml.py
xpath ¶
Run an XPath query with the library's namespace map pre-bound.
Uses :class:lxml.etree.XPath so the call works equally on raw lxml
elements and on python-docx's :class:BaseOxmlElement subclasses (whose
own xpath method does not accept a namespaces= kwarg).
Values that vary per call (style ids, numbering ids, etc.) should be
passed as **variables and referenced with $name in the
expression — this lets lxml escape them as XPath variables rather than
splicing the caller's string into the query, which avoids quote-handling
bugs and the obvious injection class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
_Element
|
Context node. |
required |
expr
|
str
|
XPath expression that may reference |
required |
**variables
|
Any
|
Values for |
{}
|
Returns:
| Type | Description |
|---|---|
list[Any]
|
The XPath result list (elements, attribute strings, etc.). Returned |
list[Any]
|
as |
Example
safe variable binding instead of f-string interpolation¶
xpath(styles_root, "./w:style[@w:styleId=$sid]", sid=style_id)¶
Source code in docx_plus/core/oxml.py
remove ¶
Detach node from its parent if it has one. No-op if already detached.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
_Element
|
Element to remove. |
required |
build_complex_field ¶
Append the 5-run complex-field sequence to p_element.
The sequence is::
<w:r><w:fldChar w:fldCharType="begin"/></w:r>
<w:r><w:instrText xml:space="preserve">INSTRUCTION</w:instrText></w:r>
<w:r><w:fldChar w:fldCharType="separate"/></w:r>
<w:r><w:t xml:space="preserve">INITIAL_TEXT</w:t></w:r>
<w:r><w:fldChar w:fldCharType="end"/></w:r>
xml:space="preserve" on the instruction and the result text
keeps leading / trailing whitespace from being normalised by Word's
XML reader.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
p_element
|
_Element
|
The underlying |
required |
instruction
|
str
|
The field instruction text (e.g. |
required |
initial_text
|
str
|
The result text shown before Word recalculates the
field. Use |
required |
Returns:
| Type | Description |
|---|---|
_Element
|
The begin |
_Element
|
field. |
Source code in docx_plus/core/oxml.py
insert_before_first_anchor ¶
insert_before_first_anchor(
parent: _Element, new_element: _Element, anchor_tags: tuple[str, ...]
) -> None
Insert new_element before the first anchor_tags match in parent.
Falls back to appending at the end if none of the anchors exist. The
pattern keeps schema-strict child ordering even when parent has a
sparse / partial set of children — most real settings.xml files
do, so capability modules building optional settings.xml children
use this to land in the right schema position.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
_Element
|
The element to insert into. |
required |
new_element
|
_Element
|
The element to insert. |
required |
anchor_tags
|
tuple[str, ...]
|
Sequence of |
required |
Source code in docx_plus/core/oxml.py
body_document_for ¶
Return the main-body :class:~docx.document.Document owning proxy.
python-docx proxies (Run, Paragraph, …) inherit .part from
Parented. For a proxy in the main document body, part is the
DocumentPart, which exposes a .document property. A header /
footer proxy is parented to a part that does not, so this raises a
clear :class:ValueError naming the operation that needs the body.
Shared by the comments and notes packages (a core utility,
so the duplication SPEC §9.1 would otherwise force is avoided).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
proxy
|
Any
|
A python-docx proxy exposing |
required |
operation
|
str
|
Human-readable name of the caller, woven into the error
message when |
'this operation'
|
Returns:
| Type | Description |
|---|---|
Document
|
The owning :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |