如何在 XML 中找到在 Python 中具有命名空间的特定值

How to find a particular value in XML which has namespaces in Python

我有一个 XML 字符串如下:

xmlstr = u'''<w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" 
xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" 
xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" 
xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" 
xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" 
xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" 
xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" 
xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" 
xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" 
xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" 
xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" 
xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" 
xmlns:o="urn:schemas-microsoft-com:office:office" 
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" 
xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" 
xmlns:v="urn:schemas-microsoft-com:vml" 
xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" 
xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" 
xmlns:w10="urn:schemas-microsoft-com:office:word" 
xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" 
xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" 
xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" 
xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" 
xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" 
xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" 
xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" 
xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
  <w:rPr>
    <w:b/>
    <w:noProof/>
    <w:sz w:val="20"/>
  </w:rPr>
  <w:drawing>
    <wp:inline distT="0" distB="0" distL="0" distR="0">
      <wp:extent cx="6324600" cy="2607945"/>
      <wp:effectExtent l="0" t="0" r="0" b="0"/>
      <wp:docPr id="6819" name="Picture 6819"/>
      <wp:cNvGraphicFramePr>
        <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
      </wp:cNvGraphicFramePr>
      <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
        <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
          <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
            <pic:nvPicPr>
              <pic:cNvPr id="6819" name="Screenshot 2019-06-27 at 11.59.23 AM.png"/>
              <pic:cNvPicPr/>
            </pic:nvPicPr>
            <pic:blipFill>
              **<a:blip r:embed="rId14" cstate="print">**
                <a:extLst>
                  <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                    <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
                  </a:ext>
                </a:extLst>
              </a:blip>
              <a:stretch>
                <a:fillRect/>
              </a:stretch>
            </pic:blipFill>
            <pic:spPr>
              <a:xfrm>
                <a:off x="0" y="0"/>
                <a:ext cx="6324600" cy="2607945"/>
              </a:xfrm>
              <a:prstGeom prst="rect">
                <a:avLst/>
              </a:prstGeom>
            </pic:spPr>
          </pic:pic>
        </a:graphicData>
      </a:graphic>
    </wp:inline>
  </w:drawing>
</w:r>
'''

上面 XML 字符串中我感兴趣的行是:

    <pic:nvPicPr>
      <pic:cNvPr id="6819" name="Screenshot 2019-06-27 at 11.59.23 AM.png"/>
      <pic:cNvPicPr/>
    </pic:nvPicPr>
    <pic:blipFill>
      <a:blip r:embed="rId14" cstate="print">

我想从 XML 字符串中提取值 "Screenshot 2019-06-27 at 11.59.23 AM.png""rId14"

我尝试使用 root.findall() 方法。但出于某种原因,我无法检索这些值。有人可以帮助我使用 Python 的 XML 库检索这些值吗?下面是我试过的代码,它显然不起作用。

from io import StringIO
from xml.etree import ElementTree

my_namespaces = dict([node for _, node in ElementTree.iterparse(StringIO(xmlstr), events=['start-ns'])])
root = ET.fromstring(xmlstr) 
print(root.findall('pic.pic', my_namespaces))

以下是获取所需数据的方法:

for pic in root.findall('.//pic:pic', my_namespaces):
    cNvPr_elem = pic.find("pic:nvPicPr/pic:cNvPr", my_namespaces)
    name_attr = cNvPr_elem.get("name")
    blip_elem = pic.find("pic:blipFill/a:blip", my_namespaces)
    embed_attr = blip_elem.get("{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed")

    print(name_attr)
    print(embed_attr)

输出:

Screenshot 2019-06-27 at 11.59.23 AM.png
rId14

备注:

    问题中的
  • pic.pic改为.//pic:pic.
  • 要获取 r:embed 属性的值,必须使用名称空间 URI。 get() 方法不采用像 findall().
  • 这样的前缀命名空间映射