微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在使用 python-pptx 操作 PowerPoint XML 时查找子元素是否存在

如何解决在使用 python-pptx 操作 PowerPoint XML 时查找子元素是否存在

在 md2pptx - 它使用 python-pptx 将 Markdown 转换为 PowerPoint - 我已经实现了一些操作 XML 树的函数

在一些地方我需要找到一个子元素(如果它存在的话)——如果它不存在就创建它。

我有一种相当笨拙的方式来搜索这个元素。我宁愿有一个像样的方式。

那么,有人可以告诉我搜索子元素存在的“正确”方法吗。

这个问题可能有一个更一般的版本 - 如何在 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 是由 python-pptx 在每个 XML 元素的基本 lxml.etree._Element 类“顶部”添加的自定义元素类层。这些自定义元素类提供了一些便利服务,特别是允许您使用元素的命名空间前缀(如本例中的 "a:fld")指定元素。

并非 python-pptx 中的所有元素都有自定义元素类,只有我们通过 API 以某种方式操作的元素类。您从 python-pptx 对象(如上面的 paragraph._p)获得的任何元素都将是 oxml 元素,但 .xpath() 调用返回的元素很可能不是(否则您会使用python-pptx 来获取它们)。 oxml 元素的元素是普通的 lxml.etree._Element 实例。

.xpath() 实例上的 lxml.etree._Element 实现需要使用所谓的“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'

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。