os.walk () Python: представление xml структуры каталогов, рекурсии

Таким образом, я пытаюсь использовать os.walk () для генерации представления XML структуры каталогов. Я, кажется, получаю тонну дубликатов. Это правильно помещает каталоги друг в друге и файлах в правильном месте для первой части XML-файла; однако, после того, как это делает это правильно, это затем продолжает пересекать неправильно. Я не совсем уверен почему....

Вот мой код:

def dirToXML(self,directory):
        curdir = os.getcwd()
        os.chdir(directory)
        xmlOutput=""

        tree = os.walk(directory)
        for root, dirs, files in tree:
            pathName = string.split(directory, os.sep)
            xmlOutput+="<dir><name><![CDATA["+pathName.pop()+"]]></name>"
            if len(files)>0:
                xmlOutput+=self.fileToXML(files)
            for subdir in dirs:
                xmlOutput+=self.dirToXML(os.path.join(root,subdir))
            xmlOutput+="</dir>"

        os.chdir(curdir)
        return xmlOutput  

fileToXML, просто синтаксические анализы список так никакая потребность волноваться об этом.

Структура каталогов просто:

images/
images/testing.xml
images/structure.xml
images/Hellos
images/Goodbyes
images/Goodbyes/foo
images/Goodbyes/bar
images/Goodbyes/square

и получающийся XML-файл стал:

<structure>
<dir>
<name>images</name>
  <files>
    <file>
      <name>structure.xml</name>
    </file>
    <file>
      <name>testing.xml</name>
    </file>
  </files>
  <dir>
    <name>Hellos</name>
  </dir>
  <dir>
    <name>Goodbyes</name>
    <dir>
      <name>foo</name>
    </dir>
    <dir>
      <name>bar</name>
    </dir>
    <dir>
      <name>square</name>
    </dir>
  </dir>
  <dir>
    <name>foo</name>
  </dir>
  <dir>
    <name>bar</name>
  </dir>
  <dir>
      <name>square</name>
    </dir>
  </dir>
  <dir>
    <name>Hellos</name>
  </dir>
  <dir>
    <name>Goodbyes</name>
    <dir>
      <name>foo</name>
    </dir>
    <dir>
      <name>bar</name>
    </dir>
    <dir>
      <name>square</name>
    </dir>
  </dir>
  <dir>
    <name>foo</name>
  </dir>
  <dir>
    <name>bar</name>
  </dir>
  <dir>
    <name>square</name>
  </dir>
</structure>

Любая справка очень ценилась бы!

5
задан Thomas 20 January 2010 в 21:19
поделиться

3 ответа

Я бы порекомендовал против использования os.walk () , поскольку вы должны сделать так много для массажирования его вывода. Вместо этого просто используйте рекурсивную функцию, использующую os.listdir () , OS.Path.join () , os.path.isdir () , и т.д. [

import os
from xml.sax.saxutils import escape as xml_escape

def DirAsXML(path):
    result = '<dir>\n<name>%s</name>\n' % xml_escape(os.path.basename(path))
    dirs = []
    files = []
    for item in os.listdir(path):
        itempath = os.path.join(path, item)
        if os.path.isdir(itempath):
            dirs.append(item)
        elif os.path.isfile(itempath):
            files.append(item)
    if files:
        result += '  <files>\n' \
            + '\n'.join('    <file>\n      <name>%s</name>\n    </file>'
            % xml_escape(f) for f in files) + '\n  </files>\n'
    if dirs:
        for d in dirs:
            x = DirAsXML(os.path.join(path, d))
            result += '\n'.join('  ' + line for line in x.split('\n'))
    result += '</dir>'
    return result

if __name__ == '__main__':
    print '<structure>\n' + DirAsXML(os.getcwd()) + '\n</structure>'

Лично я бы порекомендовал гораздо менее многословную XML-схему, положив имена в атрибуты и избавление от Группа:

import os
from xml.sax.saxutils import quoteattr as xml_quoteattr

def DirAsLessXML(path):
    result = '<dir name=%s>\n' % xml_quoteattr(os.path.basename(path))
    for item in os.listdir(path):
        itempath = os.path.join(path, item)
        if os.path.isdir(itempath):
            result += '\n'.join('  ' + line for line in 
                DirAsLessXML(os.path.join(path, item)).split('\n'))
        elif os.path.isfile(itempath):
            result += '  <file name=%s />\n' % xml_quoteattr(item)
    result += '</dir>'
    return result

if __name__ == '__main__':
    print '<structure>\n' + DirAsLessXML(os.getcwd()) + '\n</structure>'

Это дает вывод, как:

<structure>
<dir name="local">
  <dir name=".hg">
    <file name="00changelog.i" />
    <file name="branch" />
    <file name="branch.cache" />
    <file name="dirstate" />
    <file name="hgrc" />
    <file name="requires" />
    <dir name="store">
      <file name="00changelog.i" />

etc. Отказ

Если os.walk () работал больше похоже на обратные вызовы , у вас будет более легкое время.

8
ответ дан 18 December 2019 в 13:14
поделиться

Удалить две строки:

        for subdir in dirs:
            xmlOutput+=self.dirToXML(os.path.join(root,subdir))

Вы рекуните в подкаталоги; Но это избыточно, потому что ОС.

6
ответ дан 18 December 2019 в 13:14
поделиться

Я пытался использовать OS.Walk, но я увидел, что она не сработала с рекурсивной структурой дерева, которую я хотел создать в XML. Я изменил свой код следующим образом, и он дает результат, который мне нужен:

def dirToXML(self,directory):
        curdir = os.getcwd()
        os.chdir(directory)
        xmlOutput=""

        pathName = string.split(directory, os.sep)
        xmlOutput+="<dir><name><![CDATA["+pathName.pop()+"]]></name>"
        for item in os.listdir(directory):
            if os.path.isfile(os.path.join(directory, item)):
                xmlOutput+="<file><name><![CDATA["+item+"]]></name></file>"
            else :
                xmlOutput+=self.dirToXML(os.path.join(directory,item))
        xmlOutput+="</dir>"

        os.chdir(curdir)
        return xmlOutput    
0
ответ дан 18 December 2019 в 13:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: