我正在编写一个python脚本,它将在我的jenkins作业的config.xml中添加一个新的标签/元素。
这是我的脚本看起来像:-
#!/usr/bin/python
import os, fnmatch, pdb, re, string, fileinput, sys
from lxml import etree
def find(pattern, path):
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
finalresult = find('config.xml', './')
print finalresult
def writexml(filepath):
tree = etree.parse(filepath)
root = tree.getroot()
a=[]
for v in root.iter('publishers'):
for a in v:
if a.tag == "hudson.plugins.emailext.ExtendedEmailPublisher":
t1=etree.SubElement(v,'org.jenkinsci.plugins.postbuildscript.PostBuildScript',{'plugin':"postbuildscript@017"})
t2=etree.SubElement(t1,"buildSteps")
t3=etree.SubElement(t2,'hudson.tasks.Shell')
t4=etree.SubElement(t3,"command")
t4.text = "bash -x /d0/jenkins/scripts/parent-pom-enforcer.sh"
t5 = etree.SubElement(t1,'scriptOnlyIfSuccess')
t5.text = "false"
t6 = etree.SubElement(t1,'scriptOnlyIfFailure')
t6.text = "false"
t7= etree.SubElement(t1,'markBuildUnstable')
t7.text = "true"
tree.write(filepath,pretty_print=True)
findMavenProject=[]
for i in finalresult:
tree = etree.parse(i)
root = tree.getroot()
for v in root.iter('hudson.tasks.Maven'):
if v.tag == "hudson.tasks.Maven":
writexml(i)
findMavenProject.append(i)
print findMavenProject
当我执行这个脚本时,我得到以下错误:
running with cElementTree on Python 2.5+
['./jen1/config.xml', './jen2/config.xml', './jen3/config.xml', './jen4/config.xml']
Traceback (most recent call last):
File "./find-test.py", line 50, in <module>
writexml(i)
File "./find-test.py", line 41, in writexml
tree.write(filepath,pretty_print=True)
TypeError: write() got an unexpected keyword argument 'pretty_print'
我谷歌这个错误,发现,我应该使用"lxml"。我用它,但即使在那之后,我得到同样的错误。我正在使用Python 2.7.6版本.
什么线索吗?
Python标准库xml.etree.ElementTree.write()
没有pretty_print参数。
在lxml
的最新版本中该方法的版本执行。我刚刚用lxml 3.3.3测试了它,http://lxml.de/tutorial.html#serialisation上的文档提到了它。
您可能正在使用旧版本的lxml,或者不知何故仍在使用标准库的旧库副本。
tree.write(filepath,pretty_print=True)
是错误的。
正确路径:tree.write(filepath)
或tree.tostring(root, pretty_print=True)
。
详细解释:
tree
是ElementTree Objects
,而write
没有pretty_print
参数。
write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")
将元素树写入文件,如XML。File是一个文件名,或一个为写入而打开的文件对象。encoding[1]为输出编码(默认为US-ASCII)。xml_declaration控制是否应该将XML声明添加到文件中。从不使用False,始终使用True,仅当不是US-ASCII或UTF-8时使用None(默认为None)。default_namespace设置默认的XML命名空间(对于" xmlns ")。方法为"xml"、"html"或"text"(默认为"xml")。返回一个编码字符串。
xml.etree.ElementTree。文档元素
回答另一个问题,用Python打印XML:
import xml.dom.minidom
my_xml_doc = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = my_xml_doc.toprettyxml()
更新2
lxml。树确实有pretty_print
参数,如下所示:
etree.tostring(root, pretty_print=True)
lxml docs
感谢@RemcoGerlich
下面代码的问题是它使用制表符创建了重复的空行。如果您试图编辑现有的xml.
import xml.dom.minidom
xml = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = xml.toprettyxml()
解决方案:-我试了下面的代码,它为我工作。
from lxml import etree as ET
import xml.dom.minidom
def writexml(filepath):
parser = ET.XMLParser(resolve_entities=False, strip_cdata=False)
tree = ET.parse(filepath, parser)
root = tree.getroot()
a=[]
for v in root.iter('publishers'):
for a in v:
if a.tag == "hudson.plugins.emailext.ExtendedEmailPublisher":
t1=ET.SubElement(v,'org.jenkinsci.plugins.postbuildscript.PostBuildScript',{'plugin':"postbuildscript@0.17"})
t2=ET.SubElement(t1,"buildSteps")
t3=ET.SubElement(t2,'hudson.tasks.Shell')
t4=ET.SubElement(t3,"command")
t4.text = "bash -x /d0/jenkins/scripts/parent-pom-enforcer.sh"
t5 = ET.SubElement(t1,'scriptOnlyIfSuccess')
t5.text = "false"
t6 = ET.SubElement(t1,'scriptOnlyIfFailure')
t6.text = "false"
t7= ET.SubElement(t1,'markBuildUnstable')
t7.text = "true"
xml1 = xml.dom.minidom.parseString(ET.tostring(root, pretty_print=True))
pretty_xml_as_string = xml1.toprettyxml()
f = open(filepath, "w")
for v in str(pretty_xml_as_string).split("n"):
if v.strip():
f.write(v+"n")
f.close()
writexml('test.xml') #为函数writexml提供文件的完整路径