使用 python 和 lxml 修改带有命名空间的 xml 文件中的值
Modify a value in xml file with namespaces using python and lxml
Xml file:exercise.xml
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET" ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="false"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="true"/>
</Type>
</Types>
</Configuration>
要求更改:
<Param name="mode_beta" value="false"/> to <Param name="mode_beta" value="true"/>
<Param name="Mode_gama" value="true"/> to <Param name="Mode_gama" value="false"/>
使用一个使用 lxml 的小 python 脚本并将结果保存到 result.xml
请问如何做到这一点,我尝试了很多方法,但没有任何效果
这是我试过的东西
from lxml import etree as ET
tree = ET.parse('exercise.xml')
root = tree.getroot()
for val in tree.xpath("/Configuration/Types/Type[@name='F14_simpleGET']/Param[@name='mode_beta']"):
val.attrib['value'] = 'true'
tree.write('result.xml')
由于您对任何其他方法持开放态度,我建议您使用 re
(正则表达式)模块来更改 XML 文件:
import re
myXML = """
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="false"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="true"/>
</Type>
</Types>
</Configuration>
"""
modifiedXML = re.sub(r'\<Param name="mode_beta" value="false"\/>', '<Param name="mode_beta" value="true"/>' , myXML)
modifiedXML = re.sub(r'\<Param name="Mode_gama" value="true"\/>', '<Param name="Mode_gama" value="false"/>' , modifiedXML)
print(modifiedXML)
请注意,无论您是从 URL link、文件还是字符串读取文件,结果都是相同的:
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="true"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="false"/>
</Type>
</Types>
</Configuration>
您已接近最初的尝试。您只需要考虑默认命名空间。 (不过从你的问题和标签看来你已经明白了。)
在 lxml (see the docs) 中有几种不同的方法来解释命名空间。
我的首选方法是将名称空间 uri 绑定到前缀并在 xpath 中使用该前缀 (see the docs)。
示例(我编写了 tpc
前缀(基于 uri 中的图腾窗格配置);它可以是 shorter/longer/different)...
from lxml import etree
tree = etree.parse("exercise.xml")
ns = {"tpc": "http://totem.local/Pane/Configuration"}
for param in tree.xpath("/tpc:Configuration/tpc:Types/tpc:Type[@name='F14_simpleGET']/tpc:Param[@name='mode_beta']",
namespaces=ns):
param.attrib['value'] = 'true'
for param in tree.xpath("/tpc:Configuration/tpc:Types/tpc:Type[@name='F15_FixGET']/tpc:Param[@name='Mode_gama']",
namespaces=ns):
param.attrib['value'] = 'false'
tree.write("result.xml")
Xml file:exercise.xml
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET" ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="false"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="true"/>
</Type>
</Types>
</Configuration>
要求更改:
<Param name="mode_beta" value="false"/> to <Param name="mode_beta" value="true"/>
<Param name="Mode_gama" value="true"/> to <Param name="Mode_gama" value="false"/>
使用一个使用 lxml 的小 python 脚本并将结果保存到 result.xml
请问如何做到这一点,我尝试了很多方法,但没有任何效果
这是我试过的东西
from lxml import etree as ET
tree = ET.parse('exercise.xml')
root = tree.getroot()
for val in tree.xpath("/Configuration/Types/Type[@name='F14_simpleGET']/Param[@name='mode_beta']"):
val.attrib['value'] = 'true'
tree.write('result.xml')
由于您对任何其他方法持开放态度,我建议您使用 re
(正则表达式)模块来更改 XML 文件:
import re
myXML = """
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="false"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="true"/>
</Type>
</Types>
</Configuration>
"""
modifiedXML = re.sub(r'\<Param name="mode_beta" value="false"\/>', '<Param name="mode_beta" value="true"/>' , myXML)
modifiedXML = re.sub(r'\<Param name="Mode_gama" value="true"\/>', '<Param name="Mode_gama" value="false"/>' , modifiedXML)
print(modifiedXML)
请注意,无论您是从 URL link、文件还是字符串读取文件,结果都是相同的:
<Configuration xmlns="http://totem.local/Pane/Configuration">
<Types>
<Type name="F14_simpleGET" clazz="local.totem.zorg.priv.proc.F14.F14_simpleGET ttl="3600" type="SYNC">
<Param name="active_installation" value="true"/>
<Param name="mode_beta" value="true"/>
</Type>
<Type name="F15_FixGET" clazz="local.totem.zorg.priv.proc.F15.F15_fixGET" ttl="3600" type="ASYNC">
<Param name="context" value="Real"/>
<Param name="Active" value="2"/>
<Param name="Mode_gama" value="false"/>
</Type>
</Types>
</Configuration>
您已接近最初的尝试。您只需要考虑默认命名空间。 (不过从你的问题和标签看来你已经明白了。)
在 lxml (see the docs) 中有几种不同的方法来解释命名空间。
我的首选方法是将名称空间 uri 绑定到前缀并在 xpath 中使用该前缀 (see the docs)。
示例(我编写了 tpc
前缀(基于 uri 中的图腾窗格配置);它可以是 shorter/longer/different)...
from lxml import etree
tree = etree.parse("exercise.xml")
ns = {"tpc": "http://totem.local/Pane/Configuration"}
for param in tree.xpath("/tpc:Configuration/tpc:Types/tpc:Type[@name='F14_simpleGET']/tpc:Param[@name='mode_beta']",
namespaces=ns):
param.attrib['value'] = 'true'
for param in tree.xpath("/tpc:Configuration/tpc:Types/tpc:Type[@name='F15_FixGET']/tpc:Param[@name='Mode_gama']",
namespaces=ns):
param.attrib['value'] = 'false'
tree.write("result.xml")