我是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>
这就是我想要的:)
我做过什么:
为了完成这项任务,我在下面考虑了optons:
Minidom / ElementTree / lxml删除文件中的注释,并更改文件的格式。
正则表达式:不会删除评论,也不会打扰格式化。 因此,我选择了正则表达式,以下是我开始使用的,但是不起作用:(
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的新手,但我会尽力研究这些建议。
答案 0 :(得分:2)
这不是完全你想要什么,但它已经接近了。首先,避免使用正则表达式来处理xml,html和类似处理,如瘟疫。与此同时,如果您偶尔发现挑战,请不要感到惊讶。使用像lxml这样的产品。
我想,这一次,我发现了一个错误。
from lxml import etree
tree = etree.parse('shivam.xml')
element_to_change = tree.xpath('.//Composer/SocketTimeout')[0]
print(element_to_change)
element_to_change.text='60'
comment_will_follow_this = tree.xpath('.//Composer')[0]
print(comment_will_follow_this)
comment = etree.Comment('This did not work')
comment_will_follow_this.append(comment)
comment = etree.Comment('Changed this value to reduce SocketTimeout')
element_to_change.addprevious(comment)
tree.write('see_it.xml', pretty_print=True)
xpath
查找要更改的元素,以及文件中用于接收注释的位置。append
方法应该将注释或其他元素作为子元素添加到给定元素。但是,在这种情况下,我发现“这不起作用”#39;评论被添加为前面的元素评论。addprevious
能够在所需的位置添加注释,美中不足的是它无法在注释和下一个xml元素之间放置一个结束线。 / LI>
这是生成的文件。从表面上看,您会注意到原始评论是完整的。
<JavaHost>
<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>
<!--Changed this value to reduce SocketTimeout--><SocketTimeout>60</SocketTimeout>
<Enabled>true</Enabled>
<!--This did not work--></Composer>
</Domain>
</JavaHost>