Use ElementTree to add elements and sub-elements

import xml.etree.ElementTree as ET

root = ET.Element('Configuration')
student = ET.SubElement(root, 'student')
ET.SubElement(student, 'name').text = 'A'
ET.SubElement(student, 'years').text = '20'

# Test the result
import xml.dom.minidom
dom = xml.dom.minidom.parseString(ET.tostring(root))
print(dom.toprettyxml())

The result is below.

<?xml version="1.0" ?>
<Configuration>
	<student>
		<name>A</name>
		<years>20</years>
	</student>
</Configuration>

Configure logging’s behavior once for all

An example Logging to multiple destinations in Logging Cookbook shows that we can configure logging‘s behavior once and then use the new behavior everywhere.

In one file LogAgent.py, we can configure logging‘s behavior as below.

// LogAgent.py

import logging

# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    datefmt='%m-%d %H:%M',
                    filename='/temp/myapp.log',
                    filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)

In another file A, we can use logging like below.

from LogAgent import *

logger1 = logging.getLogger('myapp.area1')

logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')

In another file B, we can use logging in the same way.

from LogAgent import *

logger2 = logging.getLogger('myapp.area2')

logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')

Write XML from a string

There are two ways of writing XML from a string.

  • To an XML file[1]
    • ET.XML()
    • ET.tostring()
    • write()
  • To the memory[2]
    • ET.fromstring()

Take the xml data from [2] as an exmaple.

xmlData = """<?xml version="1.0"?>
        <data>
            <country name="Liechtenstein">
                <rank>1</rank>
                <year>2008</year>
                <gdppc>141100</gdppc>
                <neighbor name="Austria" direction="E"/>
                <neighbor name="Switzerland" direction="W"/>
            </country>
            <country name="Singapore">
                <rank>4</rank>
                <year>2011</year>
                <gdppc>59900</gdppc>
                <neighbor name="Malaysia" direction="N"/>
            </country>
            <country name="Panama">
                <rank>68</rank>
                <year>2011</year>
                <gdppc>13600</gdppc>
                <neighbor name="Costa Rica" direction="W"/>
                <neighbor name="Colombia" direction="E"/>
            </country>
        </data>"""

To an XML file

from xml.etree import ElementTree as ET

root = ET.XML(xmlData)
with open('a.xml', 'w') as f:
    f.write(ET.tostring(root).decode())

Read the xml file:

tree = ET.parse('a.xml')
rootNode = tree.getroot()
for child in rootNode:
    print(child.tag, child.attrib)
    
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

To the memory

root = ET.fromstring(xmlData)

Read the root directly:

for child in root:
    print(child.tag, child.attrib)
    
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

References

[1] https://stackoverflow.com/questions/6440115/how-do-i-parse-a-string-in-python-and-write-it-as-an-xml-to-a-new-xml-file

[2] https://docs.python.org/2/library/xml.etree.elementtree.html