разобрать xml файл и создать список файлов - PullRequest
0 голосов
/ 06 июля 2010

есть файл info.xml в каждом / var / packs / {много папок} /info.xml, где находятся разные каталоги, но с информацией о директориях в info.xml

Мне нужно проанализировать каждый{много папок} и создайте список пути к файлу, который находится внутри тегов Path, если тип файла «config», который можно найти, проверив, является ли «config» тип внутри тегов типа.

Файл info.xml будет таким,

<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>

Ответы [ 3 ]

2 голосов
/ 06 июля 2010

Это очень простой пример без обработки ошибок, который работает с очень строго определенными XML-файлами, но вы должны взять его как начало и продолжить со следующими ссылками:

Код:

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()  
1 голос
/ 07 июля 2010

Использование lxml.etree и 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()'))

Если lxml недоступен, вы также можете использовать etree API в стандартной библиотеке:

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)
0 голосов
/ 06 июля 2010

Списание этого с макушки моей головы, но здесь идет.Мы собираемся использовать os.path.walk для рекурсивного перехода в ваши каталоги и minidom для выполнения анализа.

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)

Не самый эффективный способ выполнить это, я уверен, ноЯ сделаю, если вы не ожидаете ошибок / что угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...