Python 获取具有属性的etree元素,或包含具有属性的子元素

Python 获取具有属性的etree元素,或包含具有属性的子元素,python,xml,elementtree,Python,Xml,Elementtree,我有一个XML文件要解析,我需要按id查找元素 在示例代码中,我需要找到驾驶员的姓名,但我不知道我的id是针对车辆、发动机、还是块。我想要一个能在车辆内部处理任意xml的解决方案(但驾驶员的存在是有保证的) 但我不知道如何使它适用于任何后代,而不是特定级别的Decentant。注意:下面的所有代码片段都使用lxml库。要安装,请运行:pip install lxml 您应该使用root.xpath(..)而不是root.findall(..) 如果要从给定ID中提取驱动程序名,请执行以下操作:

我有一个XML文件要解析,我需要按id查找元素

在示例代码中,我需要找到
驾驶员的姓名
,但我不知道我的id是针对
车辆
发动机
、还是
。我想要一个能在
车辆
内部处理任意xml的解决方案(但
驾驶员
的存在是有保证的)


但我不知道如何使它适用于任何后代,而不是特定级别的Decentant。

注意:下面的所有代码片段都使用
lxml
库。要安装,请运行:
pip install lxml

您应该使用
root.xpath(..)
而不是
root.findall(..)

如果要从给定ID中提取驱动程序名,请执行以下操作:

>>> vehicle_id = "16"
>>> xpath("//vehicle[@id='16' or .//*[@id='16']]/driver/text()")
['Bob Johnson']
>>> i = '16'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']
>>> i = '532'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']
>>> i = '113'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']
更新:要获取给定
id
的驱动程序名,请执行以下操作:

>>> vehicle_id = "16"
>>> xpath("//vehicle[@id='16' or .//*[@id='16']]/driver/text()")
['Bob Johnson']
>>> i = '16'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']
>>> i = '532'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']
>>> i = '113'
>>> a.xpath("//vehicle[@id='%s' or .//*[@id='%s']]/driver/text()"%(i,i))
['Bob Johnson']

如果您知道
id
,但不知道该
id
是否来自车辆、引擎或区块,则可以使用XPath表达式来接近它,但必须使用而不是
xml.etree.ElementTree
(它的XPath支持非常有限)。使用轴:

这将打印:

  • Bob Johnson
    如果
    输入id
    将是
    16
    532
    113
  • Dave Edwards
    如果
    输入id
    将是
    452
    212
    381

完整的工作示例:

import lxml.etree as ET

data = """
<road>
    <vehicle id="16">
        <driver>Bob Johnson</driver>
        <engine id="532">
            <type>V8</type>
            <block id="113">
                <material>Aluminium</material>
            </block>
        </engine>
    </vehicle>
    <vehicle id="452">
        <driver>Dave Edwards</driver>
        <engine id="212">
            <type>Inline 6</type>
            <block id="381">
                <material>Cast Iron</material>
            </block>
        </engine>
    </vehicle>
</road>
"""

root = ET.fromstring(data)
for input_id in [16, 532, 113, 452, 212, 381]:
    print(root.xpath(".//*[@id='%s']/ancestor-or-self::vehicle/driver" % input_id)[0].text)

好的,但是我如何找到哪一个是我的id?如果我有“381”的身份证,我怎么知道那是给“戴夫·爱德华兹”的,不是给“鲍勃·约翰逊”的?你能解释一下吗?是否要为具有给定ID的车辆查找驾驶员?是,或为包含具有给定ID的元素的车辆查找驾驶员。我的ID可能是针对车辆、发动机或缸体的,但是我需要找到驱动程序。我得到了一个错误:
AttributeError:'xml.etree.ElementTree.Element'对象没有属性'xpath'
我加载我的xml就像:
tree=etree.parse('file.xml')
root=tree.getroot()
我需要以不同的方式加载它吗?我需要一个单独的库吗?您使用的是
lxml
<代码>从lxml导入etree?编辑:可能不会。请使用
lxml
库执行所有特定于XML的操作。现成的
ElementTree
缺少许多标准功能。这可能是个人偏好的问题,但由于您最终使用的是
lxml.etree
,我认为应该首选
祖先或自我。从性能角度来看,它肯定会更快。
input_id = "your ID"
print(root.xpath(".//*[@id='%s']/ancestor-or-self::vehicle/driver" % input_id)[0].text)
import lxml.etree as ET

data = """
<road>
    <vehicle id="16">
        <driver>Bob Johnson</driver>
        <engine id="532">
            <type>V8</type>
            <block id="113">
                <material>Aluminium</material>
            </block>
        </engine>
    </vehicle>
    <vehicle id="452">
        <driver>Dave Edwards</driver>
        <engine id="212">
            <type>Inline 6</type>
            <block id="381">
                <material>Cast Iron</material>
            </block>
        </engine>
    </vehicle>
</road>
"""

root = ET.fromstring(data)
for input_id in [16, 532, 113, 452, 212, 381]:
    print(root.xpath(".//*[@id='%s']/ancestor-or-self::vehicle/driver" % input_id)[0].text)
Bob Johnson
Bob Johnson
Bob Johnson
Dave Edwards
Dave Edwards
Dave Edwards