简体   繁体   中英

TypeError: write() got an unexpected keyword argument 'pretty_print'

I am writing a python script which will append a new Tag/elment in config.xml of my jenkins job.

This is how my script looks like:-

#!/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

When I execute this script, I get following error:

  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'

I googled this error and found that, I should use "lxml". I used it but even after that I am getting the same error. I am using Python 2.7.6 version..

Any clue?

The tree.write(filepath,pretty_print=True) was wrong.

The right way: tree.write(filepath) or tree.tostring(root, pretty_print=True) .


Detail explaination:

tree was a ElementTree Objects , who's write has no pretty_print argument.

write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")

Writes the element tree to a file, as XML. file is a file name, or a file object opened for writing. encoding [1] is the output encoding (default is US-ASCII). xml_declaration controls if an XML declaration should be added to the file. Use False for never, True for always, None for only if not US-ASCII or UTF-8 (default is None). default_namespace sets the default XML namespace (for “xmlns”). method is either "xml", "html" or "text" (default is "xml"). Returns an encoded string.

xml.etree.ElementTree.Element docs


UPDATE

To answer another question, Pretty printing XML in Python :

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()

UPDATE2

lxml.etree does have the pretty_print argument as follows:

etree.tostring(root, pretty_print=True)

lxml docs

special thanks to @RemcoGerlich

Python's standard library xml.etree.ElementTree.write() does not have the pretty_print argument.

The version of that method that is in recent versions of lxml does . I just tested it with lxml 3.3.3, and the docs at http://lxml.de/tutorial.html#serialisation mention it.

You are either using an old version of lxml, or somehow still using the standard library's older copy of the library.

The issue with below code is that it creates duplicate empty lines with tabs. if you are trying to edit the existing 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()

Solution:- I tried below code and it worked for me.

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') #provide full path of the file as arg to function writexml.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM