You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python ElementTree提取符合条件的XML用户节点name属性

问题描述

需要从给定XML文件中提取<user>节点的name属性值,筛选条件为该<user>节点下属的<job>节点需同时满足kind="al"和run="jps"。使用ElementTree尝试提取时,因getparent()方法不支持而失败。

目标XML内容

<maruti>
    <usrDirectory>/usr</usrDirectory>
    <shareDirectory>/share</shareDirectory>
    <jobLogDirectory>/logs</jobLogDirectory>
    <clients>
        <client>nexa-asia</client>
    </clients>

    <imax>
        <uri>imaxs://imax-asia.fb.bda.com:123</uri>
        <rootDn>o=lbr</rootDn>
        <pend>ou=nexa-asia,ou=clients,o=lbr</pend>
        <password>password</password>
    </imax>

    <enabling-aling-tags>
        <tag>alingDisabled</tag>
    </enabling-aling-tags>

    <maxh>999</maxh>

    <defaults>
        <default type="slone">
            <user>pot</user>
            <exec>/usr/local/smarts/utils/runals.sh</exec>
            <env>
                <var name="ALARM">/taj/63123.lbr/ALARM</var>
                <var name="TODAY">/taj/63123.lbr/TODAY</var>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="slanamb">
            <user>pot</user>
            <exec>/usr/local/smarts/utils/runals.sh</exec>
            <env>
                <var name="ALARM">/taj/63123.lbr/ALARM</var>
                <var name="TODAY">/taj/63123.lbr/TODAY</var>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="slaljps">
            <user>pot</user>
            <exec>/use-ALARM/runmrts.sh</exec>
            <env>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="slanjps">
            <user>pot</user>
            <exec>/use-ALARM/runmrts.sh</exec>
            <env>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="cmj">
            <user>pot</user>
            <exec>/use-ALARM/runmrts.sh</exec>
            <env>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="cbj">
            <user>pot</user>
            <exec>/use-ALARM/runmrts.sh</exec>
            <env>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
        <default type="slm">
            <user>favactor</user>
            <exec>/usr/local/actdrive/actdrive</exec>
            <args>
                <arg name="config">/usr01/lbr/conf/lbr-naming.properties</arg>
            </args>
        </default>
        <default type="tata">
            <user>pot</user>
            <exec>/use-ALARM/tataals.sh</exec>
            <env>
                <var name="jps_HOME">/usr/juju</var>
            </env>
        </default>
    </defaults>

    <groups>
        <user name="nexa_sit" annvday="20221003" make="one">
            <jobs>
                <job kind="al" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
                <job kind="vm" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
            </jobs>
        </user>


        <user name="nexa_tsx" annvday="20230714" make="two">
            <jobs>
                <job kind="al" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
                <job kind="vm" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
            </jobs>
        </user>


        <user name="nexatwo_bvk" annvday="20221003" make="one">
            <jobs>
                <job kind="al" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
                <job kind="vm" run="jps">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
            </jobs>
        </user>

        <user name="nexaone_bvk" annvday="20221003" make="one">
            <jobs>
                <job kind="al" run="ips">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
                <job kind="vm" run="ips">
                    <args>
                        <arg name="level">5000</arg>
                    </args>
                </job>
            </jobs>
        </user>

       </groups>
   </maruti>

尝试的代码

import xml.etree.ElementTree as ET
tree = ET.parse('text.xml')
root = tree.getroot()
for sub in root.findall(".//user/jobs/job"):
 if (sub.attrib["run"] == 'java' and sub.attrib["kind"] == 'al'):
  print sub.getparent()

预期输出

nexa_sit
nexa_tsx
nexatwo_bvk

解决方案

方法1:通过XPath向上遍历父节点

利用XPath的..语法获取父节点,先定位符合条件的<job>,再逐层向上找到<user>节点:

import xml.etree.ElementTree as ET
tree = ET.parse('text.xml')
root = tree.getroot()

# 直接筛选出满足kind="al"且run="jps"的job节点
for job in root.findall(".//job[@kind='al'][@run='jps']"):
    # 先找到jobs节点,再找到其父节点user
    user_node = job.find('../..')
    print(user_node.attrib['name'])

方法2:遍历user节点并检查子节点

先获取所有<user>节点,再逐个检查其下是否存在符合条件的<job>:

import xml.etree.ElementTree as ET
tree = ET.parse('text.xml')
root = tree.getroot()

for user in root.findall(".//user"):
    # 检查当前user下是否有满足条件的job
    matched_jobs = user.findall("./jobs/job[@kind='al'][@run='jps']")
    if matched_jobs:
        print(user.attrib['name'])

原代码错误分析

  1. 条件匹配错误:原代码中判断run="java",但需求是run="jps",导致无法筛选到目标节点。
  2. 方法过时:getparent()方法在新版ElementTree中已被移除,推荐使用XPath的..语法来获取父节点,避免依赖内部属性。

内容的提问来源于stack exchange,提问作者upkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:59:52