如何解析位于多个层次结构下的 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))
<?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))