【发布时间】:2018-08-05 05:06:23
【问题描述】:
我是 python 新手,正在尝试修改本地系统中存在的一些 xml 配置文件。
输入:我有一个包含以下内容的 xml 文件(比如 Test.xml)。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<JavaHost xmlns="SomeInfo/v1.1">
<Domain>
<MessageProcessor>
<!-- This comment should not be removed and all formating should be untouched -->
<SocketTimeout>500</SocketTimeout>
</MessageProcessor>
<!-- This comment should not be removed and all formating should be untouched -->
<Composer>
<SocketTimeout>5000</SocketTimeout>
<Enabled>true</Enabled>
</Composer>
</Domain>
</JavaHost>
我想要实现的目标: 我想实现以下两件事:
第 1 部分: 我想将 SocketTimeout 标记的值(仅在 composer 标记下)修改为 60,并且还想添加这样的注释(例如更改此值以减少 SocketTimeout)。 因此文件 Test.xml 应如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<JavaHost xmlns="SomeInfo/v1.1">
<MessageProcessor>
<!-- This comment should not be removed and all formating should be untouched -->
<SocketTimeout>500</SocketTimeout>
</MessageProcessor>
<!-- This comment should not be removed and all formating should be untouched -->
<Composer>
<!-- Changed this value to reduce SocketTimeout -->
<SocketTimeout>60</SocketTimeout>
<Enabled>true</Enabled>
</Composer>
</Domain>
</JavaHost>
第 2 部分: 在文件 Test.xml 中,我想在 Domain 标签下添加一个新标签,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<JavaHost xmlns="SomeInfo/v1.1">
<MessageProcessor>
<!-- This comment should not be removed and all formating should be untouched -->
<SocketTimeout>500</SocketTimeout>
</MessageProcessor>
<!-- comment should not be removed and all formatting should be untouched -->
<Composer>
<!-- Changed this value to reduce SocketTimeout -->
<SocketTimeout>60</SocketTimeout>
<Enabled>true</Enabled>
</Composer>
<New_tag>
<!-- New Tag -->
<Enabled>true</Enabled>
</New_tag>
</Domain>
</JavaHost>
这就是我想要的:)
我已经尝试过:
为了完成这项任务,我考虑了以下选项:
Minidom/ElementTree/lxml 删除文件中的 cmets 并更改文件的格式。
正则表达式:不删除 cmets,也不干扰格式化。 因此,我选择了正则表达式,下面是我开始使用的,但不起作用:(
import os, re
# set the working directory
os.chdir('C:\\Users\\Dell\\Desktop\\')
# open the source file and read it
fh = open('C:\\Users\\Dell\\Desktop\\Test.xml', 'r')
subject = fh.read()
fh.close()
pattern = re.compile(r"\[<Composer>\].*?\[/<Composer>\]")
#Replace
result = pattern.sub(lambda match: match.group(0).replace('<SocketTimeout>500</SocketTimeout>','<SocketTimeout>60</SocketTimeout>') ,subject)
# write the file
f_out = open('C:\\Users\\Dell\\Desktop\\Test.xml', 'w')
f_out.write(result)
f_out.close()
任何实现我想要的或纠正错误的想法都将是非常可观的。 虽然我是 python 新手,但会尽我所能提出建议。
【问题讨论】:
-
显示您尝试的 lxml 代码,您声称不保留 cmets 和格式。
-
感谢 ekhumoro 的快速回复,我没有尝试过 lxml,但我从 stakoverflow 上的各种问题和答案中了解到,它删除了 cmets。如果不是这种情况,您是否可以共享代码 sn-p 来实现这一点?我是新手,正在学习,但如果我得到一些像算法这样的短代码,我可以尝试编辑和编写代码。
-
没有问题 ekhumoro
标签: python regex xml lxml elementtree