Parsing XML with LXML and Python
Question: I have the following XML:

    
    
    <nfl>
      <season season="2012"/>
        <conference label="AFC">
          <division label="Eastern Division">
            <team city="Buffalo" name="Bills"  alias="Buf" />
            <team city="Miami" name="Dolphins"  alias="Mia" />
            <team city="New England" name="Patriots"  alias="NE" />
            <team city="New York" name="Jets"  alias="NYJ" />
          </division>
          <division label="Western Division">
            <team city="Denver" name="Broncos"  alias="Den" />
            <team city="Kansas City" name="Chiefs"  alias="KC" />
            <team city="Oakland" name="Raiders"  alias="Oak" />
            <team city="San Diego" name="Chargers"  alias="SD" />
          </division>
          <division label="Northern Division">
            <team city="Cincinnati" name="Bengals"  alias="Cin" />
            <team city="Cleveland" name="Browns"  alias="Cle" />
            <team city="Pittsburgh" name="Steelers"  alias="Pit" />
            <team city="Baltimore" name="Ravens"  alias="Bal" />
          </division>
          <division label="Southern Division">
            <team city="Houston" name="Texans"  alias="Hou" />
            <team city="Tennessee" name="Titans"  alias="Ten" />
            <team city="Indianapolis" name="Colts"  alias="Ind" />
            <team city="Jacksonville" name="Jaguars"  alias="Jac" />
        </division>
      </conference>
      <conference label="NFC">
        <division label="Eastern Division">
          <team city="Dallas" name="Cowboys"  alias="Dal" />
          <team city="New York" name="Giants"  alias="NYG" />
          <team city="Philadelphia" name="Eagles"  alias="Phi" />
          <team city="Washington" name="Redskins"  alias="Was" />
        </division>
        <division label="Western Division">
          <team city="St. Louis" name="Rams"  alias="StL" />
          <team city="Arizona" name="Cardinals"  alias="Ari" />
          <team city="San Francisco" name="49ers"  alias="SF" />
          <team city="Seattle" name="Seahawks"  alias="Sea" />
        </division>
        <division label="Northern Division">
          <team city="Chicago" name="Bears"  alias="Chi" />
          <team city="Detroit" name="Lions"  alias="Det" />
          <team city="Green Bay" name="Packers"  alias="GB" />
          <team city="Minnesota" name="Vikings"  alias="Min" />
        </division>
        <division label="Southern Division">
          <team city="Atlanta" name="Falcons"  alias="Atl" />
          <team city="New Orleans" name="Saints"  alias="NO" />
          <team city="Tampa Bay" name="Buccaneers"  alias="TB" />
          <team city="Carolina" name="Panthers"  alias="Car" />
      </division>
    </conference>
    
    </nfl>
    

I want to load into my model, the team "city", "name" and "alias" along with
the parent "division label", "conference label" and "season".

In Python, I iterate through the data as follows:

    
    
    from lxml import etree
    doc = etree.parse('thisxmlfile.xml')
    for s in doc.xpath('//season'):
        for c in doc.xpath('//conference'):
            for t in doc.xpath('//conference/division/team'):
                print s.get('season'), c.get('label'), t.get('city'), t.get('name'), t.get('alias')
    

But of course, it iterates through all "team" tags twice - once for each
"conference" tag. What I want to do is iterate through all "team" tags once
and get the parent "division label", parent "conference label" and parent
"season season".

Pretty sure I need to reference XPATH Axes and was looking for some help?

The output I'm looking for is:

    
    
    2012 AFC Buffalo Bills Buf
    2012 AFC Miami Dolphins Mia
    2012 AFC New England Patriots NE
    .
    .
    .
    2012 NFC New Orleans Saints NO
    2012 NFC Tampa Bay Buccaneers TB
    2012 NFC Carolina Panthers Car
    

Note: the above output does not include the "division label" but once I figure
out how to get the "conference label", it should be easy.

Thanks in advance for any help.


Answer: Here is how you can get the wanted output:

    
    
    from lxml import etree
    
    doc = etree.parse('thisxmlfile.xml')
    
    # There is only one "season" element
    season = doc.find('season').get('season')     
    
    # XPath query relative to root node
    for conference in doc.xpath('conference'):
        # XPath query relative to "conference" node     
        for team in conference.xpath('division/team'):     
            print season, conference.get('label'),
            print team.get('city'), team.get('name'), team.get('alias')
    

