Найти - Пользователи
Полная версия: дерево директорий в xml
Начало » Python для новичков » дерево директорий в xml
1
xost
Добрый всем день, питон начал изучать совсем недавно, читаю учебник на интуите, дошёл до xml. Поставил себе задачку, сформировать структуру файлов и директорий в xml файл. Вот такое решение у меня получилось с использованием SAX:

#!/usr/bin/python

from xml.sax.saxutils import XMLGenerator
import os,sys,datetime

class dir2xml:
def __init__(self,filename="tree_%s.xml"%datetime.date.today()):
self.filename=filename
try:
self.fh=open(filename,"w")
except IOError,error:
print error.err
return error.err
try:
self.xml=XMLGenerator(self.fh)
except:
print "Error creating XML object"
return -1

def __del__(self):
self.fh.close()

def toxml(self,dir_):
self.xml.startElement("directory",{"dirname":dir_})
items=os.listdir(dir_)
for item in items:
fullname=os.path.join(dir_,item)
if os.path.isdir(fullname):
self.toxml(fullname)
else:
ext=item.split(".")
self.xml.startElement("file",{"size":str(os.path.getsize(fullname)),"type":ext[-1]})
self.xml.characters(item)
self.xml.endElement("file")
self.xml.endElement("directory")

a=dir2xml()
a.toxml(sys.argv[1])
Ну во первых хотелось бы конечно услышать критику этого кода (где что нерационально, а где может и вообще глупо по неопытности написано). Но главный вопрос, сейчас хочу решить ту же самую задачку с помощью minidom и вот тут я застрял окончательно, поправил вариант с SAX вот на такой:

#!/usr/bin/python

from xml.dom import minidom
import os,sys,datetime

class dir2xml:
def __init__(self,filename="tree_%s.xml"%datetime.date.today()):
self.filename=filename
try:
self.fh=open(filename,"w")
except IOError,error:
print error.err
return error.err
try:
self.dom=minidom.Document()
except:
print "Error creating XML object"
return -1

def __del__(self):
self.fh.close()

def toxml(self,dir_):
e1=self.dom.createElement("Directory")
e1.setAttribute("dirname",dir_)
self.dom.appendChild(e1)
items=os.listdir(dir_)
for item in items:
fullname=os.path.join(dir_,item)
if os.path.isdir(fullname):
self.toxml(fullname)
else:
ext=item.split(".")
e2=self.dom.createElement("file")
e2.setAttribute("size",str(os.path.getsize(fullname)))
e2.setAttribute("type",ext[-1])
e2.appendChild(self.dom.createTextNode(item))
e1.appendChild(e2)
return self.dom

a=dir2xml()
xml=a.toxml(sys.argv[1])
print xml.toprettyxml()
работает, только при условии если нет, поддиректорий, т.е. не работает рекурсия, выдаёт исключение:
xml.dom.HierarchyRequestErr: two document elements disallowed

Что забавно, нарыл вот эту ссылку: http://code.activestate.com/recipes/305313/ уже после того как сначала сюда вопрос запостил, но тоже выдаёт только список файлов в директории первого уровня.

Прошу совета, как можно данную проблему решить ?

Спасибо.
balu
Если тебе это нужно практически то не имеет смысла использовать для этого xml.
xost
balu
Если тебе это нужно практически то не имеет смысла использовать для этого xml.
ну на самом деле, тут основная цель - решить задачу и получить какой никакой навык ) ну а ко всему прочему, надо есть желание написать скрипт для подбивания изменений в дереве, с учётом размера и сохранением статистики.

Так что всё-же прошу помощи ) Потому как сам пока решить не могу……. и ещё….. хочется использовать именно minidom ))) Ну вот такой вот я упёртый ) опять же, это не объясняется ни чем кроме как “хочу решить задачу”
PooH
У вас при рекурсивном вызове toxml в него должна передаваться нода в которую будут вставляться данные подкаталога, а сейчас вы пытаетесь вставить несколько элементов в корень XML, а по стандарту он должен быть один, о чем вам питон и ругается.

Ну и вообще, зачем организовывать класс там где достаточно функции? открытие файла в __init__ и закрытие в __del__ - не делайте так. параметр filename в __init__ по умолчанию - потенциально опасно лучше поставить filename=None, а в методе уже проверить и вычислить. Ошибки съедаете в try/except - мне как пользователю лучше видеть трайсбэк, а не ваше невнятное “ну не шмогла я, не шмогла”. Да и вообще я бы формировал XML не через minidom, а простым текстовым выводом.

Ну как то вот так :rolleyes:
Ed
xost
Что забавно, нарыл вот эту ссылку: http://code.activestate.com/recipes/305313/ уже после того как сначала сюда вопрос запостил, но тоже выдаёт только список файлов в директории первого уровня.
У меня этот пример работает вполне себе нормально и формирует вложенную структуру каталогов и файлы в них.

Ваш код pylint оценил в 0.83/10. Негусто.
balu
xost
ну на самом деле, тут основная цель - решить задачу и получить какой никакой навык
Если цель получить навык работы xml или передать куда-то данные, то это одно дело.
Если цель задачи - создать дерево, то это из пушки по воробьям http://alexott-ru.blogspot.com/2009/01/xml.html.
xost
PooH
У вас при рекурсивном вызове toxml в него должна передаваться нода в которую будут вставляться данные подкаталога, а сейчас вы пытаетесь вставить несколько элементов в корень XML, а по стандарту он должен быть один, о чем вам питон и ругается.

Ну и вообще, зачем организовывать класс там где достаточно функции? открытие файла в __init__ и закрытие в __del__ - не делайте так. параметр filename в __init__ по умолчанию - потенциально опасно лучше поставить filename=None, а в методе уже проверить и вычислить. Ошибки съедаете в try/except - мне как пользователю лучше видеть трайсбэк, а не ваше невнятное “ну не шмогла я, не шмогла”. Да и вообще я бы формировал XML не через minidom, а простым текстовым выводом.

Ну как то вот так :rolleyes:
Спасибо за подсказку про ноду, всё получилось :) ну а что касается того что зря я всё это классом и try/except так это обусловлено исключительно что я учусь и стараюсь пробовать как можно больше возможностей, ньюансов использовать, пусть даже и неоправданно, чтоб так сказать на корочку записалось. Простым SAX у меня достаточно быстро получилось всё реализовать, но для дальнейшей задумки скрипта мне кажется не плохо было бы работать с DOM объектом, вот и заморочился.

PS: объясните, пожалуйста, почему filename по умолчанию опасно в __init__ ? и почему открытие и закрытие файла в __init__ , __del__ не делать ?

Ещё раз спасибо за помощь.
xost
balu
xost
ну на самом деле, тут основная цель - решить задачу и получить какой никакой навык
Если цель получить навык работы xml или передать куда-то данные, то это одно дело.
Если цель задачи - создать дерево, то это из пушки по воробьям http://alexott-ru.blogspot.com/2009/01/xml.html.
Да, я ж написал, первоочередная цель - получить навык :) Но за ваше мнение спасибо :)
PooH
xost
PS: объясните, пожалуйста, почему filename по умолчанию опасно в __init__ ?
Значения параметров по умолчанию вычисляются в момент когда метод определяется. Если ваш класс будет использован в постоянно работающей программе, то файл будет создаваться с одним и тем же именем - с датой запуска программы
xost
и почему открытие и закрытие файла в __init__ , __del__ не делать ?
По той же причине, что и в Java: момент вызова __del__ точно не определен, это не C++. Да и вообще, чем меньшее время открыт ресурс (в данном случае файл) тем лучше.
xost
PooH
xost
PS: объясните, пожалуйста, почему filename по умолчанию опасно в __init__ ?
Значения параметров по умолчанию вычисляются в момент когда метод определяется. Если ваш класс будет использован в постоянно работающей программе, то файл будет создаваться с одним и тем же именем - с датой запуска программы
xost
и почему открытие и закрытие файла в __init__ , __del__ не делать ?
По той же причине, что и в Java: момент вызова __del__ точно не определен, это не C++. Да и вообще, чем меньшее время открыт ресурс (в данном случае файл) тем лучше.
Ок, спасибо за разъяснения.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB