如何解析位于多个层次结构下的 XML 文件?

How do I parse XML file which is under multiple hierarchy?

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.3 r1808647">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
      <stringProp name="TestPlan.comments"></stringProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <stringProp name="TestPlan.user_define_classpath"></stringProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
          <boolProp name="LoopController.continue_forever">false</boolProp>
          <stringProp name="LoopController.loops">1</stringProp>
        </elementProp>
        <stringProp name="ThreadGroup.num_threads">1</stringProp>
        <stringProp name="ThreadGroup.ramp_time">1</stringProp>
        <longProp name="ThreadGroup.start_time">1522132570000</longProp>
        <longProp name="ThreadGroup.end_time">1522132570000</longProp>
        <boolProp name="ThreadGroup.scheduler">false</boolProp>
        <stringProp name="ThreadGroup.duration"></stringProp>
        <stringProp name="ThreadGroup.delay"></stringProp>
      </ThreadGroup>
      <hashTree>
        <com.googlecode.jmeter.plugins.webdriver.config.ChromeDriverConfig guiclass="com.googlecode.jmeter.plugins.webdriver.config.gui.ChromeDriverConfigGui" testclass="com.googlecode.jmeter.plugins.webdriver.config.ChromeDriverConfig" testname="jp@gc - Chrome Driver Config" enabled="true">
          <stringProp name="WebDriverConfig.proxy_type">SYSTEM</stringProp>
          <stringProp name="WebDriverConfig.proxy_pac_url"></stringProp>
          <stringProp name="WebDriverConfig.http_host"></stringProp>
          <intProp name="WebDriverConfig.http_port">8080</intProp>
          <boolProp name="WebDriverConfig.use_http_for_all_protocols">true</boolProp>
          <stringProp name="WebDriverConfig.https_host"></stringProp>
          <intProp name="WebDriverConfig.https_port">8080</intProp>
          <stringProp name="WebDriverConfig.ftp_host"></stringProp>
          <intProp name="WebDriverConfig.ftp_port">8080</intProp>
          <stringProp name="WebDriverConfig.socks_host"></stringProp>
          <intProp name="WebDriverConfig.socks_port">8080</intProp>
          <stringProp name="WebDriverConfig.no_proxy">localhost</stringProp>
          <boolProp name="WebDriverConfig.maximize_browser">false</boolProp>
          <boolProp name="WebDriverConfig.reset_per_iteration">false</boolProp>
          <boolProp name="WebDriverConfig.dev_mode">false</boolProp>
          <stringProp name="ChromeDriverConfig.chromedriver_path">chromedriver.exe</stringProp>
          <boolProp name="ChromeDriverConfig.android_enabled">false</boolProp>
        </com.googlecode.jmeter.plugins.webdriver.config.ChromeDriverConfig>
        <hashTree/>
        <com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler guiclass="com.googlecode.jmeter.plugins.webdriver.sampler.gui.WebDriverSamplerGui" testclass="com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler" testname="jp@gc - WebDriver Sampler" enabled="true">
          <stringProp name="WebDriverSampler.script">import org.openqa.selenium.support.ui.WebDriverWait;</stringProp>
          <stringProp name="WebDriverSampler.parameters"></stringProp>
          <stringProp name="WebDriverSampler.language">beanshell</stringProp>
        </com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler>
        <hashTree/>
      </hashTree>
    </hashTree>
    <WorkBench guiclass="WorkBenchGui" testclass="WorkBench" testname="WorkBench" enabled="true">
      <boolProp name="WorkBench.save">true</boolProp>
    </WorkBench>
    <hashTree/>
  </hashTree>
</jmeterTestPlan>

以上是我 XML 文件的第一部分。我需要改变的地方 从那里我需要编辑

 <boolProp name="WebDriverConfig.reset_per_iteration">false</boolProp>

我已经尝试过很多次尝试使用多种类型的代码,例如

def cache_it2(datafile):
    tree = et.parse(datafile)
    tree.find('jmeterTestPlan/hashTree/hashTree/ThreadGroup/longProp/ThreadGroup.end_time').text = 'false'
    tree.write(datafile)

它对我不起作用,因为它给出了

AttributeError: 'NoneType' object has no attribute 'text'

我在其他代码中也发现了同样的错误,如果有任何解决方法,请告诉我。

嗯,你在find中使用的路径显然是错误的。 我建议您重新阅读文档,尤其是关于 supported XPATH syntax

import xml.etree.ElementTree as ET
tree = ET.parse(xml_file)
root = tree.getroot() # element: jmeterTestPlan

虽然这对我有用

print(root.find('./hashTree/hashTree/ThreadGroup/longProp[@name="ThreadGroup.end_time"]').text)

使用这样的东西可能会更好。 特别是如果你想替换多个值:

names_and_values = {
    "WebDriverConfig.maximize_browser" : "true",
    "WebDriverConfig.reset_per_iteration": "true",
    # ...
}

for name, value in names_and_values.items():
    element = next(root.iterfind(f'.//*[@name="{name}"]'))
    element.text = value

print(ET.tostring(root))