Thread: Python xml

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    27
    Rep Power
    0

    Python xml


    Hi, so I have this xml file.
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <catalog>
    	<cd>
    		<title>Empire Burlesque</title>
    		<artist sex="male">Bob Dylan</artist>
    		<country>USA</country>
    		<company>Columbia</company>
    		<price>10.90</price>
    		<year>1985</year>
    	</cd>
    	<cd>
    		<title>Hide your heart</title>
    		<artist sex="female">Bonnie Tyler</artist>
    		<country>UK</country>
    		<company>CBS Records</company>
    		<price>9.90</price>
    		<year>1988</year>
    	</cd>
    	<cd>
    		<title>Greatest Hits</title>
    		<artist sex="female">Dolly Parton</artist>
    		<country>USA</country>
    		<company>RCA</company>
    		<price>9.90</price>
    		<year>1982</year>
    	</cd>
    	<cd>
    		<title>Black angel</title>
    		<artist sex="mixed">Savage Rose</artist>
    		<country>EU</country>
    		<company>Mega</company>
    		<price>10.90</price>
    		<year>1995</year>
    	</cd>
    	<cd>
    		<title>1999 Grammy Nominees</title>
    		<artist sex="mixed">Many</artist>
    		<country>USA</country>
    		<company>Grammy</company>
    		<price>10.20</price>
    		<year>1999</year>
    	</cd>
    	<cd>
    		<title>Unchain my heart</title>
    		<artist sex="male">Joe Cocker</artist>
    		<country>USA</country>
    		<company>EMI</company>
    		<price>8.20</price>
    		<year>1987</year>
    	</cd>
    </catalog>
    I need return the name of the title of the last CD as a string, but I can't figure out how except for returning the first CD name.
    Here's my code:
    Code:
    def get_last_title(xmlstr):
      tree = ET.parse('cd_catalog.xml')
      root = tree.getroot()
      return root.find('cd').find('title').text
    I also need to return the price of the most expensive CD as a float value, but I'm not exactly sure on how to go about it.
    Code:
    def find_most_pricy(xmlstr):
      tree = ET.parse('cd_catalog.xml')
      root = tree.getroot()
      return
    Any help is greatly appreciated!
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481
    Code:
    import xml.etree.ElementTree as ET
    
    class dwlxml:
    
        '''
            front end to findall
        '''
    
        def __init__(self,root):
            self.root = root
    
        def __call__(self,tag):
            '''
                return in a list all Elements that match the tag
            '''
            ROOTS = []
            dwlxml.findall(self.root,tag,ROOTS.append)
            return ROOTS
    
        @staticmethod
        def findall(root,tag,append): # staticmethod is used to hide this function which is too hard for the common person to use.
            if tag == root.tag:
                append(root)
            else:
                for child in root:
                    dwlxml.findall(child,tag,append)
    
    tree = ET.parse('catalog.xml')
    root = tree.getroot()
    cds = dwlxml(root)('cd')
    
    titles = [element.find('title').text for element in cds] # ALL TITLES
    print('"last" title: {}'.format(titles[-1]))
    
    prices = [element.find('price').text for element in cds] # ALL PRICES
    PRICES = [float(a) for a in prices]
    i = PRICES.index(max(PRICES)) # index of priciest cd
    print('{} costs {}'.format(titles[i],prices[i]))
    Last edited by b49P23TIvg; February 8th, 2013 at 09:38 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    27
    Rep Power
    0
    Is there a way of going about it without using class dwlxml and just somehow implementing the (self.root,tag,ROOTS.append)? or dwlxml.findall(child,tag,append)? under def get_last_title(xmlstr): and def find_most_pricy(xmlstr): ? I know that's probably more repetitive but is that possible? If so, would you mind guiding me in the right direction?
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,966
    Rep Power
    481

    Interesting use of sum


    Code:
    import xml.etree.ElementTree as ET
    
    XML = '''<?xml version="1.0" encoding="ISO-8859-1"?>
    <catalog><cd><title>Empire Burlesque</title><artist sex="male">Bob Dylan</artist><country>USA</country><company>Columbia</company><price>10.90</price><year>1985</year></cd><cd><title>Unchain my heart</title><artist sex="male">Joe Cocker</artist><country>USA</country><company>EMI</company><price>8.20</price><year>1987</year></cd></catalog>
    '''
    
    if True:                                  # from string
        root = ET.fromstring(XML)
    else:                                     # from file
        tree = ET.parse('catalog.xml')
        root = tree.getroot()
     
    def findall(root,tag):
        return [root] if tag == root.tag else sum((findall(child,tag) for child in root),[])
        return ((tag == root.tag) and [root]) or sum((findall(child,tag) for child in root),[]) # dwl dislikes this version
    
    cds = findall(root,'cd')
    
    titles = [element.find('title').text for element in cds] # ALL TITLES
    print('"last" title: {}'.format(titles[-1]))
    
    prices = [element.find('price').text for element in cds] # ALL PRICES
    PRICES = [float(a) for a in prices]
    i = PRICES.index(max(PRICES)) # index of priciest cd
    print('{} costs {}'.format(titles[i],prices[i]))
    Yes, I can remove the class.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    27
    Rep Power
    0
    Thanks man! You're awesome!

    Btw, Do you know how we go about sorting a list of specific artists in alphabetical order?

    I have this code and I got it to print out the right artists I'm looking for, but I can't figure out how to sort it so it's in alphabetical order.

    Code:
    def get_uk_artists(xmlstr):
      tree = ET.parse('cd_catalog.xml')
      root = tree.getroot()
      cds = [cd for cd in root.findall('cd') if cd.findtext('country') == 'UK']
      artist = [element.find('artist').text for element in cds]
      return artist
    Do we use the sorted() function or something like that?
  10. #6
  11. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2005
    Posts
    618
    Rep Power
    65
    sorted(myartistlist) will work
    however, if you want to sort by last name, then you have have to do something extra
    Real Programmers always confuse Christmas and Halloween because Oct31 == Dec25

IMN logo majestic logo threadwatch logo seochat tools logo