如何使用 Python-Docx 向元素添加自定义 XML?
How do I Add Custom XML to An Element Using Python-Docx?
我一直在尝试为我的 table 设置文本换行,但 python-docx 中没有实现。
到目前为止一切顺利,我已经隔离出 MS Word 将 <w:tblpPr w:leftFromText="180" w:rightFromText="180" w:vertAnchor="text" w:tblpY="1"/>
作为子项添加到 table 属性元素中,因此我只需要将其注入到我的 table 中python-docx.
我真的很接近。因为我能够在库中找到要添加子项的元素 class。但是,我的问题在于 w: 命名空间,因为它不允许我构建一个带有“:”字符的 Element 标记。我尝试了两种方法,都失败了。
tblPrElement = Element('w:tblpPr ', {'w:leftFromText': '180', 'w:rightFromText': '180', 'w:vertAnchor': 'text', 'w:tblpY': '1' })
tblPrElement = parse_xml('<w:tblpPr w:leftFromText="180" w:rightFromText="180" w:vertAnchor="text" w:tblpY="1"/>')
如果我尝试省略 w: ...
document = Document()
table = document.add_table(rows=1, cols=3)
tblPrElement = parse_xml('<tblpPr leftFromText="180" rightFromText="180" vertAnchor="text" tblpY="1"/>')
table._tblPr.append(tblPrElement)
...然后文档生成但 ms word 无法打开它,因为 xml 然后看起来像这样:
如果您想使用 lxml 通过元素附加 XML,您必须在创建元素时提供 python-docx 的命名空间映射 (docx.oxml.nsmap
)。
在标签名称中插入命名空间的语法是 {namespacevalue}tagname
。
例如,<{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tblpPr/>
您可以使用以下方法将 table 设置为使用 XML 的文本换行。
def set_text_wrap_around_table(table):
w_namespace = '{' + nsmap['w'] + '}'
tblPrElement = Element('{w}tblpPr'.format(w=w_namespace),
{'{w}leftFromText'.format(w=w_namespace): '180',
'{w}rightFromText'.format(w=w_namespace): '180',
'{w}vertAnchor'.format(w=w_namespace): 'text',
'{w}tblpY'.format(w=w_namespace): '1'},
nsmap)
table._tblPr.append(tblPrElement)
考虑 lxml 的 QName() 功能版本以避免字符串格式化:
from lxml import etree
...
def set_text_wrap_around_table(table):
tblPrElement = etree.Element(
etree.QName(nsmap["w"], "tblpPr"),
{
etree.QName(nsmap["w"], "leftFromText"): '180',
etree.QName(nsmap["w"], "rightFromText"): '180',
etree.QName(nsmap["w"], "vertAnchor"): 'text',
etree.QName(nsmap["w"], "tblpY"): '1'
},
nsmap
)
table._tblPr.append(tblPrElement)
python-docx 有一个 qn
方法用于创建元素。
def qn(tag):
"""
Stands for "qualified name", a utility function to turn a namespace
prefixed tag name into a Clark-notation qualified tag name for lxml. For
example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``.
"""
它允许您键入带有命名空间前缀的 XML。
from docx.oxml.ns import qn
def set_text_wrap_around_table(table):
tbl_properties_element = Element(qn('w:tblpPr'),
{
qn('w:leftFromText'): '180',
qn('w:rightFromText'): '180',
qn('w:vertAnchor'): 'text',
qn('w:tblpY'): '1'
})
table._tblPr.append(tbl_properties_element)
如果您要创建的元素已经在 python-docx 中定义了 class,您可以使用 docx.oxml.OxmlElement
创建它,例如,您可以创建段落 运行 元素 class 像这样:
from docx.oxml import OxmlElement
run_element = OxmlElement('w:r')
这具有将其可能的子项定义为属性等的额外好处。
我一直在尝试为我的 table 设置文本换行,但 python-docx 中没有实现。
到目前为止一切顺利,我已经隔离出 MS Word 将 <w:tblpPr w:leftFromText="180" w:rightFromText="180" w:vertAnchor="text" w:tblpY="1"/>
作为子项添加到 table 属性元素中,因此我只需要将其注入到我的 table 中python-docx.
我真的很接近。因为我能够在库中找到要添加子项的元素 class。但是,我的问题在于 w: 命名空间,因为它不允许我构建一个带有“:”字符的 Element 标记。我尝试了两种方法,都失败了。
tblPrElement = Element('w:tblpPr ', {'w:leftFromText': '180', 'w:rightFromText': '180', 'w:vertAnchor': 'text', 'w:tblpY': '1' })
tblPrElement = parse_xml('<w:tblpPr w:leftFromText="180" w:rightFromText="180" w:vertAnchor="text" w:tblpY="1"/>')
如果我尝试省略 w: ...
document = Document()
table = document.add_table(rows=1, cols=3)
tblPrElement = parse_xml('<tblpPr leftFromText="180" rightFromText="180" vertAnchor="text" tblpY="1"/>')
table._tblPr.append(tblPrElement)
...然后文档生成但 ms word 无法打开它,因为 xml 然后看起来像这样:
如果您想使用 lxml 通过元素附加 XML,您必须在创建元素时提供 python-docx 的命名空间映射 (docx.oxml.nsmap
)。
在标签名称中插入命名空间的语法是 {namespacevalue}tagname
。
例如,<{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tblpPr/>
您可以使用以下方法将 table 设置为使用 XML 的文本换行。
def set_text_wrap_around_table(table):
w_namespace = '{' + nsmap['w'] + '}'
tblPrElement = Element('{w}tblpPr'.format(w=w_namespace),
{'{w}leftFromText'.format(w=w_namespace): '180',
'{w}rightFromText'.format(w=w_namespace): '180',
'{w}vertAnchor'.format(w=w_namespace): 'text',
'{w}tblpY'.format(w=w_namespace): '1'},
nsmap)
table._tblPr.append(tblPrElement)
考虑 lxml 的 QName() 功能版本以避免字符串格式化:
from lxml import etree
...
def set_text_wrap_around_table(table):
tblPrElement = etree.Element(
etree.QName(nsmap["w"], "tblpPr"),
{
etree.QName(nsmap["w"], "leftFromText"): '180',
etree.QName(nsmap["w"], "rightFromText"): '180',
etree.QName(nsmap["w"], "vertAnchor"): 'text',
etree.QName(nsmap["w"], "tblpY"): '1'
},
nsmap
)
table._tblPr.append(tblPrElement)
python-docx 有一个 qn
方法用于创建元素。
def qn(tag):
"""
Stands for "qualified name", a utility function to turn a namespace
prefixed tag name into a Clark-notation qualified tag name for lxml. For
example, ``qn('p:cSld')`` returns ``'{http://schemas.../main}cSld'``.
"""
它允许您键入带有命名空间前缀的 XML。
from docx.oxml.ns import qn
def set_text_wrap_around_table(table):
tbl_properties_element = Element(qn('w:tblpPr'),
{
qn('w:leftFromText'): '180',
qn('w:rightFromText'): '180',
qn('w:vertAnchor'): 'text',
qn('w:tblpY'): '1'
})
table._tblPr.append(tbl_properties_element)
如果您要创建的元素已经在 python-docx 中定义了 class,您可以使用 docx.oxml.OxmlElement
创建它,例如,您可以创建段落 运行 元素 class 像这样:
from docx.oxml import OxmlElement
run_element = OxmlElement('w:r')
这具有将其可能的子项定义为属性等的额外好处。