2015-01-28 14 views
5

Sto cercando di analizzare sotto XML utilizzando Python ElementTree per l'output del prodotto come di seguito. Sto provando a scrivere moduli per i migliori elementi per stamparli. Tuttavia è un po 'complicato dato che l'elemento di categoria può o non può avere proprietà e un elemento di registro può avere all'interno un elemento di categoria.Python di analisi XML ricorsivo utilizzando ElementTree

ho fatto riferimento alla domanda precedente in questo argomento, ma non hanno costituiti da elementi annidati con lo stesso nome

My Code: http://pastebin.com/Fsv2Xzqf

work.xml: 
<suite id="1" name="MainApplication"> 
<displayNameKey>my Application</displayNameKey> 
<displayName>my Application</displayName> 
<application id="2" name="Sub Application1"> 
<displayNameKey>sub Application1</displayNameKey> 
<displayName>sub Application1</displayName> 
<category id="2423" name="about"> 
<displayNameKey>subApp.about</displayNameKey> 
<displayName>subApp.about</displayName> 
<category id="2423" name="comms"> 
<displayNameKey>subApp.comms</displayNameKey> 
<displayName>subApp.comms</displayName> 
<property id="5909" name="copyright" type="string_property" width="40"> 
<value>2014</value> 
</property> 
<property id="5910" name="os" type="string_property" width="40"> 
<value>Linux 2.6.32-431.29.2.el6.x86_64</value> 
</property> 
</category> 
<property id="5908" name="releaseNumber" type="string_property" width="40"> 
<value>9.1.0.3.0.54</value> 
</property> 
</category> 
</application> 
</suite> 

uscita dovrebbe essere, come di seguito:

Suite: MainApplication 
    Application: Sub Application1 
     Category: about 
      property: releaseNumber | 9.1.0.3.0.54 
      category: comms 
       property: copyright | 2014 
       property: os | Linux 2.6.32-431.29.2.el6.x86_64 

Qualsiasi suggerimento nella giusta direzione sarebbe di aiuto.

+0

Dai anche un'occhiata a ['xmltodict'] (https://github.com/martinblech/xmltodict) che genera un dittato python per te. –

risposta

7
import xml.etree.ElementTree as ET 
tree = ET.ElementTree(file='work.xml') 

indent = 0 
ignoreElems = ['displayNameKey', 'displayName'] 

def printRecur(root): 
    """Recursively prints the tree.""" 
    if root.tag in ignoreElems: 
     return 
    print ' '*indent + '%s: %s' % (root.tag.title(), root.attrib.get('name', root.text)) 
    global indent 
    indent += 4 
    for elem in root.getchildren(): 
     printRecur(elem) 
    indent -= 4 

root = tree.getroot() 
printRecur(root) 

USCITA:

Suite: MainApplication 
    Application: Sub Application1 
     Category: about 
      Category: comms 
       Property: copyright 
        Value: 2014 
       Property: os 
        Value: Linux 2.6.32-431.29.2.el6.x86_64 
      Property: releaseNumber 
       Value: 9.1.0.3.0.54 

Questo è più vicino ho potuto ottenere in 5 minuti. Dovresti semplicemente chiamare in modo ricorsivo una funzione del processore e questo dovrebbe fare attenzione. È possibile migliorare da questo punto :)


È inoltre possibile definire funzione del gestore per ogni tag e mettere tutti in un dizionario per una facile ricerca. Quindi puoi verificare se hai una funzione di gestione appropriata per quel tag, quindi chiamare quel altro solo continuare con la stampa cieca. Per esempio:

HANDLERS = { 
    'property': 'handle_property', 
    <tag_name>: <handler_function> 
} 

def handle_property(root): 
    """Takes property root element and prints the values.""" 
    data = ' '*indent + '%s: %s ' % (root.tag.title(), root.attrib['name']) 
    values = [] 
    for elem in root.getchildren(): 
     if elem.tag == 'value': 
      values.append(elem.text) 
    print data + '| %s' % (', '.join(values)) 

# printRecur would get modified accordingly. 
def printRecur(root): 
    """Recursively prints the tree.""" 
    if root.tag in ignoreElems: 
     return 

    global indent 
    indent += 4 

    if root.tag in HANDLERS: 
     handler = globals()[HANDLERS[root.tag]] 
     handler(root) 
    else: 
     print ' '*indent + '%s: %s' % (root.tag.title(), root.attrib.get('name', root.text)) 
     for elem in root.getchildren(): 
      printRecur(elem) 

    indent -= 4 

Uscita con sopra:

Suite: MainApplication 
    Application: Sub Application1 
     Category: about 
      Category: comms 
       Property: copyright | 2014 
       Property: os | Linux 2.6.32-431.29.2.el6.x86_64 
      Property: releaseNumber | 9.1.0.3.0.54 

mi trovo molto utile, piuttosto che mettere tonnellate di if/else nel codice.

+0

Grazie Jatin, questo mi ha dato una buona idea su come affrontare questo problema. – Ara

+0

Siete i benvenuti :) –

Problemi correlati