2015-01-28 25 views
5

'u kullanarak özyinelemeli XML ayrıştırma python'u Python ElementTree'yi kullanarak aşağıdakini aşağıdaki gibi ayrıştırmaya çalışıyorum. Bunları basmak için en iyi öğeler için modüller yazmaya çalışıyorum. Ancak, kategori öğesi özellik taşıyabilecek veya sahip olamayacağı ve kataegor elemanın içinde bir kategori elemanına sahip olabileceği için biraz zor.ElementTree

Bu konudaki önceki soruya atıfta ettik, ancak aynı adla iç içe elemanlardan oluşur vermedi

Benim Kod: 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> 

Çıktı aşağıdaki gibi olmalıdır:

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 

Doğru yönde herhangi bir işaretçi yardımcı olacaktır.

+0

Ayrıca, sizin için bir python dict'i yaratan ['xmltodict'] (https://github.com/martinblech/xmltodict) adresine de bakabilirsiniz. –

cevap

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) 

ÇIKIŞ:

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 

Bu 5 dakika içinde alabilir yakın. Sadece numaralı özyinelemeli olarak bir işlemci işlevini çağırmalısınız ve bu dikkat çeker. Sen Ayrıca her etiket için işleyici işlevi tanımlayın ve kolay arama için bir sözlükte hepsini koyabilirsiniz :)


bu noktadan üzerinde artırabilir. Daha sonra bu etiket için uygun bir işleyici işleviniz olup olmadığını kontrol edebilir, daha sonra bunu körü körüne yazdırmaya devam edebilirsiniz.

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 

Çıktı yukarıdaki ile: Örneğin:

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 

ben kodunda eğer/else bu çok kullanışlı ziyade koyarak ton bulabilirsiniz.

+0

Teşekkürler Jatin, bu bana bu probleme nasıl yaklaşılacağı konusunda iyi bir fikir verdi. – Ara

+0

Bir şey değil :) –

İlgili konular