簡體   English   中英

如何使用 Python-Docx 將自定義 XML 添加到元素?

[英]How do I Add Custom XML to An Element Using Python-Docx?

我一直在嘗試為我的表格獲取文本換行,這在 python-docx 中沒有實現。

在此處輸入圖像描述

到目前為止一切順利,我已經隔離出 MS Word 添加<w:tblpPr w:leftFromText="180" w:rightFromText="180" w:vertAnchor="text" w:tblpY="1"/>作為孩子到表屬性元素,所以我只需要將它注入到 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 看起來像這樣:

在此處輸入圖像描述

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')

這具有將其可能的子項定義為屬性等的額外好處。

如果要使用 lxml 到 append 和 XML 使用元素,則必須在創建元素時提供 python-docx 的命名空間 map( docx.oxml.nsmap )。

在標簽名稱中插入命名空間的語法是{namespacevalue}tagname

例如, <{http://schemas.openxmlformats.org/wordprocessingml/2006/main}tblpPr/>

下面是根據您的需要使用字符串格式插入命名空間值的示例。

tblPrElement = Element('{{{w}}}tblpPr'.format(w=nsmap['w']),
                           {'{{{w}}}leftFromText'.format(w=nsmap['w']): '180',
                            '{{{w}}}rightFromText'.format(w=nsmap['w']): '180',
                            '{{{w}}}vertAnchor'.format(w=nsmap['w']): 'text',
                            '{{{w}}}tblpY'.format(w=nsmap['w']): '1'},
                           nsmap)

請注意,它在w周圍使用三重{ ,因為除了{w}用於插入命名空間值之外,我們還需要在最終字符串中的值周圍使用{ }並轉義 string.format 需要連續兩個{{ }}

考慮 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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM