如何使用 ElementTree 检索特定标签信息?

how to retrieve specific tag information using ElementTree?

我想检索特定的标签属性。 file 标签包含子标签 filename 并且基于这个字段我想决定是否应该采用 modification

换句话说:如果filename值包含.tar我想打印修改时间。

在下面的示例中,我希望打印 2020-07-15T06:41:12.000Z

我尝试这样做了 2 个小时,但没有成功,所以我将非常感谢任何让我更接近解决方案的提示。 这是代码,但没有打印也没有添加到 dates 列表:

import xml.etree.ElementTree as ET

tree = ET.parse(r"C:\path\to\file\logs.xml")
root = tree.getroot()
dates = []
for filetag in root.findall('.//{*}file'):
    for filename in filetag.findall('../{*}filename'):
        if ".tar" in filename.attrib['value']:
            print(filename)
            dates.append(filename)

这是XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="user@11.11.111.11" start="2020-07-22T10:01:12.939Z">
  <ls>
    <destination value="/folder/processing" />
    <files>
      <file>
        <filename value="." />
        <type value="d" />
        <modification value="2020-07-22T08:57:28.000Z" />
        <permissions value="rwxrwsrwx" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
      <file>
        <filename value=".." />
        <type value="d" />
        <modification value="2020-07-22T08:51:15.000Z" />
        <permissions value="rwxrwxrwx" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
      <file>
        <filename value="package_tsp200715092001_20200715074120.tar" />
        <type value="-" />
        <size value="4014536192" />
        <modification value="2020-07-15T06:41:12.000Z" />
        <permissions value="rw-rw-rw-" />
        <owner value="1005" />
        <group value="1005" />
      </file>
      <file>
        <filename value="package_tsp200715092001_20200715074120" />
        <type value="d" />
        <modification value="2020-07-15T06:41:59.000Z" />
        <permissions value="rwxr-Sr--" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
    </files>
    <result success="true" />
  </ls>
</session>
for filename in filetag.findall('../{*}filename'):

因为 .. 这会在 file 元素的 parent 中查找 filename(即,作为同级file)。应该是单个.

此外,命名空间 通配符已添加到 Python 3.8。您没有指明您使用的 Python 版本,因此这也可能是一个问题。

无论如何,你最好“正确地”使用命名空间而不是寻找捷径,它有点冗长但几乎没有困难:

NS = {'scp': 'http://winscp.net/schema/session/1.0'}
for filetag in root.findall('.//scp:file', NS):
    for filename in filetag.findall('./scp:filename', NS):
        if ".tar" in filename.get('value', ''):
            print(filename)
            dates.append(filename)

下面是一个衬垫:

import xml.etree.ElementTree as ET

xml = '''

<session xmlns="http://winscp.net/schema/session/1.0" name="user@11.11.111.11" start="2020-07-22T10:01:12.939Z">
  <ls>
    <destination value="/folder/processing" />
    <files>
      <file>
        <filename value="." />
        <type value="d" />
        <modification value="2020-07-22T08:57:28.000Z" />
        <permissions value="rwxrwsrwx" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
      <file>
        <filename value=".." />
        <type value="d" />
        <modification value="2020-07-22T08:51:15.000Z" />
        <permissions value="rwxrwxrwx" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
      <file>
        <filename value="package_tsp200715092001_20200715074120.tar" />
        <type value="-" />
        <size value="4014536192" />
        <modification value="2020-07-15T06:41:12.000Z" />
        <permissions value="rw-rw-rw-" />
        <owner value="1005" />
        <group value="1005" />
      </file>
      <file>
        <filename value="package_tsp200715092001_20200715074120" />
        <type value="d" />
        <modification value="2020-07-15T06:41:59.000Z" />
        <permissions value="rwxr-Sr--" />
        <owner value="1000130000" />
        <group value="0" />
      </file>
    </files>
    <result success="true" />
  </ls>
</session>
'''

NS = {'scp': 'http://winscp.net/schema/session/1.0'}
root = ET.fromstring(xml)
tar_files_dates = [f.find('./scp:modification',NS).attrib['value'] for f in root.findall('.//scp:file',NS) if '.tar' in f.find('./scp:filename',NS).attrib['value']]
print(tar_files_dates)

输出

['2020-07-15T06:41:12.000Z']