سؤال

لذلك أحاول استخدام 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>

أي مساعدة سيكون محل تقدير كبير!

هل كانت مفيدة؟

المحلول

أوصي بعدم الاستخدام 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 أقل بكثير ، ووضع أسماء في سمات والتخلص من <files> مجموعة:

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

إلخ.

لو os.walk() عملت أكثر مثل expatعمليات الاسترجاعات ، سيكون لديك وقت أسهل منه.

نصائح أخرى

قم بإزالة الخطين:

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

أنت تتكرر في الدلائل الفرعية. لكن هذا زائد ، لأن OS.Walk يتكرر نفسه.

كنت أحاول استخدام 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    
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top