使用 python-pptx 操作 PowerPoint XML 时查找子元素(如果存在)
Finding A Child Element If It Exists When Manipulating PowerPoint XML With python-pptx
在 md2pptx - 使用 python-pptx 将 Markdown 转换为 PowerPoint - 我实现了一些操作 XML 树的函数。
在一些地方我需要找到一个子元素(如果它存在),如果不存在则创建它。
我有一种相当老套的方法来搜索这个元素。我宁愿有一个像样的方法。
所以,有人可以 post 告诉我搜索子元素是否存在的“正确”方法。
这个问题可能有一个更一般的版本——如何在 python-pptx 的上下文中操作 XML。我也可以为此使用参考。 (是的,我可以阅读 python-pptx 代码并且经常阅读 - 但概要会帮助我正确理解。)
为这项工作使用 XPath 几乎总是正确的答案。
例如,如果您想获取一个段落的所有 a:fld
个子元素来实现与文本字段有关的内容:
# --- get <a:p> XML element of paragraph ---
p = paragraph._p
# --- use XPath to get all the `<a:fld>` child elements ---
flds = p.xpath("./a:fld")
# --- do something with them ---
for fld in flds:
do_fieldy_thing(fld)
.xpath()
调用的结果是与作为其参数提供的 str
XPath 表达式相匹配的零个或多个项目的列表。如果只能有零个或一个结果,通常会这样处理它:
if flds:
do_fieldy_thing(flds[0])
当“起始”元素(在本例中为 p
)不是已定义的 oxml
元素时,就会出现复杂情况。 oxml
是一层自定义元素 classes,由 python-pptx
添加到每个 XML 元素的基础 lxml.etree._Element
class“之上”。这些自定义元素 classes 提供了一些便利服务,特别是允许您使用它们的名称空间前缀指定元素(如本例中的 "a:fld"
)。
并非 python-pptx
中的所有元素都有自定义元素 class,只有那些我们通过 API 以某种方式操作的元素。您从 python-pptx
对象(如上面的 paragraph._p
)获得的任何元素都将是 oxml 元素,但是 .xpath()
调用返回的元素很可能不是(否则您会使用python-pptx
得到它们)。 非 oxml 元素的元素是纯 lxml.etree._Element
个实例。
lxml.etree._Element
实例上的 .xpath()
实现需要使用所谓的“Clark 名称”,它类似于:"{http://schemas.openxmlformats.org/drawingml/2006/main}fld"
而不是 "a:fld"
。
您可以使用 pptx.oxml.ns.qn()
函数从命名空间前缀的标签名称创建 Clark 名称:
>>> from pptx.oxml.ns import qn
>>> qn("a:fld")
'{http://schemas.openxmlformats.org/drawingml/2006/main}fld'
在 md2pptx - 使用 python-pptx 将 Markdown 转换为 PowerPoint - 我实现了一些操作 XML 树的函数。
在一些地方我需要找到一个子元素(如果它存在),如果不存在则创建它。
我有一种相当老套的方法来搜索这个元素。我宁愿有一个像样的方法。
所以,有人可以 post 告诉我搜索子元素是否存在的“正确”方法。
这个问题可能有一个更一般的版本——如何在 python-pptx 的上下文中操作 XML。我也可以为此使用参考。 (是的,我可以阅读 python-pptx 代码并且经常阅读 - 但概要会帮助我正确理解。)
为这项工作使用 XPath 几乎总是正确的答案。
例如,如果您想获取一个段落的所有 a:fld
个子元素来实现与文本字段有关的内容:
# --- get <a:p> XML element of paragraph ---
p = paragraph._p
# --- use XPath to get all the `<a:fld>` child elements ---
flds = p.xpath("./a:fld")
# --- do something with them ---
for fld in flds:
do_fieldy_thing(fld)
.xpath()
调用的结果是与作为其参数提供的 str
XPath 表达式相匹配的零个或多个项目的列表。如果只能有零个或一个结果,通常会这样处理它:
if flds:
do_fieldy_thing(flds[0])
当“起始”元素(在本例中为 p
)不是已定义的 oxml
元素时,就会出现复杂情况。 oxml
是一层自定义元素 classes,由 python-pptx
添加到每个 XML 元素的基础 lxml.etree._Element
class“之上”。这些自定义元素 classes 提供了一些便利服务,特别是允许您使用它们的名称空间前缀指定元素(如本例中的 "a:fld"
)。
并非 python-pptx
中的所有元素都有自定义元素 class,只有那些我们通过 API 以某种方式操作的元素。您从 python-pptx
对象(如上面的 paragraph._p
)获得的任何元素都将是 oxml 元素,但是 .xpath()
调用返回的元素很可能不是(否则您会使用python-pptx
得到它们)。 非 oxml 元素的元素是纯 lxml.etree._Element
个实例。
lxml.etree._Element
实例上的 .xpath()
实现需要使用所谓的“Clark 名称”,它类似于:"{http://schemas.openxmlformats.org/drawingml/2006/main}fld"
而不是 "a:fld"
。
您可以使用 pptx.oxml.ns.qn()
函数从命名空间前缀的标签名称创建 Clark 名称:
>>> from pptx.oxml.ns import qn
>>> qn("a:fld")
'{http://schemas.openxmlformats.org/drawingml/2006/main}fld'