在使用python将Markdown转换为md2pptx的PowerPoint中,我实现了一些操纵XML树的函数。
在一些地方,我需要找到一个子元素(如果它存在的话)--如果不存在,就创建它。
我有一种相当讨厌的方法来寻找这个元素。我宁愿有个像样的方法。
所以,有人能给我发个“正确”的方式来寻找一个子元素的存在吗?
这个问题可能有一个更普遍的版本--如何在python的上下文中操作XML。我也需要一些参考资料。(是的,我可以阅读python-pptx代码,而且经常读-但是一个概要可以帮助我正确地理解它。)
发布于 2021-07-25 12:15:18
在这项工作中使用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表达式匹配的零项或多项的列表。如果只能有0或一个结果,则通常这样处理它:
if flds:
do_fieldy_thing(flds[0])
当“启动”元素(在本例中为p
)不是定义的oxml
元素时,就会出现复杂的情况。oxml
是python-pptx
为每个XML元素“在”基类的基础上添加的一层自定义元素类。这些自定义元素类提供了一些方便的服务,特别是允许您使用名称空间前缀指定元素(如本例中的"a:fld"
)。
并非python-pptx
中的所有元素都有自定义元素类,只有我们通过API以某种方式操作的元素类。从python-pptx
对象(如上面的paragraph._p
)获得的任何元素都将是oxml元素,但是.xpath()
调用返回的元素很可能不是(否则您将使用python-pptx
获取它们)。不是oxml元素的元素是普通的lxml.etree._Element
实例。
.xpath()
实例上的lxml.etree._Element
实现需要使用所谓的“克拉克名称”,它看起来类似于:"{http://schemas.openxmlformats.org/drawingml/2006/main}fld"
而不是"a:fld"
。
可以使用pptx.oxml.ns.qn()
函数从名称空间前缀标记名创建克拉克名称:
>>> from pptx.oxml.ns import qn
>>> qn("a:fld")
'{http://schemas.openxmlformats.org/drawingml/2006/main}fld'
https://stackoverflow.com/questions/68521561
复制