2010-07-06 5 views
0

il y a un fichier info.xml sous chaque/var/paquets/{} de nombreux dossiers /info.xml où sont différents répertoires mais avec l'information des dirs dans info.xmlParse fichier xml et créer une liste de fichiers

Je dois analyser tous les {nombreux dossiers} et créer une liste du chemin de fichier qui se trouve dans les balises Path si le type de fichier est "config" qui peut être trouvé en vérifiant si "config" est le type dans les balises de type.

Le fichier info.xml wil être comme celui-ci,

<Files> 
    <File> 
     <Path>usr/share/doc/dialog/samples/form1</Path> 
     <Type>doc</Type> 
     <Size>1222</Size> 
     <Uid>0</Uid> 
     <Gid>0</Gid> 
     <Mode>0755</Mode> 
     <Hash>49744d73e8667d0e353923c0241891d46ebb9032</Hash> 
    </File> 
    <File> 
     <Path>usr/share/doc/dialog/samples/form3</Path> 
     <Type>config</Type> 
     <Size>1294</Size> 
     <Uid>0</Uid> 
     <Gid>0</Gid> 
     <Mode>0755</Mode> 
     <Hash>f30277f73e468232c59a526baf3a5ce49519b959</Hash> 
    </File> 
</Files> 

Répondre

2

Voici exemple très basique sans traitement des erreurs et fonctionne avec des fichiers XML très strictement définis, mais vous devriez le prendre comme un début et continuer les liens suivants:

Le code:

import os 
import os.path 
from xml.dom.minidom import parse 


def parse_file(path): 
    files = [] 
    try: 
     dom = parse(path) 
     for filetag in dom.getElementsByTagName('File'): 
      type = filetag.getElementsByTagName('Type')[0].firstChild.data 
      if type == 'config': 
       path = tag.getElementsByTagName('Path')[0].firstChild.data 
       files.append(path) 
     dom.unlink() 
    except: 
     raise 
    return files 


def main(): 
    files = [] 
    for root, dirs, files in os.walk('/var/packs'): 
     if 'info.xml' in files: 
      files += parse_file(os.path.join(root, 'info.xml')) 
    print 'The list of desired files:', files 


if __name__ == '__main__': 
    main() 
0

La rédaction de ce du haut de ma tête, mais va ici. Nous allons utiliser os.path.walk pour descendre récursivement dans vos répertoires et minidom pour faire l'analyse.

import os 
from xml.dom import minidom 

# opens a given info.xml file and prints out "Path"'s contents 
def parseInfoXML(filename): 
    doc = minidom.parse(filename) 
    for fileNode in doc.getElementsByTagName("File"): 
     # warning: we assume the existence of a Path node, and that it contains a Text node 
     print fileNode.getElementsByTagName("Path")[0].childNodes[0].data 
    doc.unlink() 

def checkDirForInfoXML(arg, dirname, names): 
    if "info.xml" in names: 
     parseInfoXML(os.path.join(dirname, "info.xml")) 

# recursively walk the directory tree, calling our visitor function to check for info.xml in each dir 
# this will include packs as well, so be sure that there's no info.xml in there 
os.path.walk("/var/packs" , checkDirForInfoXML, None) 

pas la façon la plus efficace pour l'accomplir, je suis sûr, mais il va le faire si vous ne vous attendez pas d'erreurs/whatever.

+1

Juste une remarque: os.path.walk est déprécié et a été supprimé en 3.0 en faveur de os.walk(). http://docs.python.org/library/os.path.html#os.path.walk – dmedvinsky

+0

Aha, merci. Je vis malheureusement encore à l'âge de pierre Python 2.6, heh. – Faisal

1

En utilisant lxml.etree et XPath:

files = [] 
for root, dirnames, filenames in os.walk('/var/packs'): 
    for filename in filenames: 
     if filename != 'info.xml': 
      continue 
     tree = lxml.etree.parse(os.path.join(root, filename)) 
     files.extend(tree.getroot().xpath('//File[Type[text()="config"]]/Path/text()')) 

Si lxml n'est pas disponible, vous pouvez également utiliser le etree API dans la bibliothèque standard:

files = [] 
for root, dirnames, filenames in os.walk('/var/packs'): 
    for filename in filenames: 
     if filename != 'info.xml': 
      continue 
     tree = xml.etree.ElementTree.parse(os.path.join(root, filename)) 
     for file_node in tree.findall('File'): 
      type_node = file_node.find('Type') 
      if type_node is not None and type_node.text == 'config': 
       path_node = file_node.find('Path') 
       if path_node is not None: 
        files.append(path_node.text)