Скрипт для создания XML списка файлов каталога - PullRequest
1 голос
/ 29 января 2011

Может кто-нибудь предложить сценарий для создания XML-представления всех файлов, а также файлов в подкаталоге (в Windows) по типу файла.Например, если текущим именем каталога является mypics, то для всех jpg

<?xml version="1.0" encoding="utf-8"?>
<images xmlns="http://mydomain.com/images" version="1.0">
  <image>
      <big_url>myassets/pics/funnypics/big_pics/down.jpg</big_url>
  </image>
  <image>      
      <big_url>assets/pics/funnypics/big_pics/spider.jpg</big_url>
  </image>  
</images>

затем для pdf

<?xml version="1.0" encoding="utf-8"?>
<pdfs xmlns="http://mydomain.com/pdf" version="1.0">
  <pdf>
      <big_url>myassets/pics/funnypics/big_pics/down.pdf</big_url>
  </pdf>
  <pdf>      
      <big_url>assets/pics/funnypics/big_pics/spider.pdf</big_url>
  </pdf>  
</pdfs>

, поскольку число типов файлов не ограничено, я могу расширить предложенный скрипт

Ответы [ 3 ]

2 голосов
/ 29 января 2011

Это должно помочь вам начать:

#!/usr/bin/perl
use warnings;
use strict;
use File::Find;
use XML::Simple;

my $dir = shift || '.';

my %files;
find \&by_extension, $dir;
print XMLout \%files;

sub by_extension {
    return if /^\./;                    # skip dotfiles
    return unless -f;                   # skip non-files
    return unless /\.([^.]+)$/;         # skip if no filename extension
    my $ext = lc $1;                    # ignore case
    $File::Find::name =~ s#^\Q$dir/##;  # trim starting directory name
    push @{$files{$ext . '_files'}{$ext}}, $File::Find::name;
}
1 голос
/ 29 января 2011

Следующий код на Perl поможет (возможно, за вычетом отступа XML-файла):

package FilesToXml;
use IO;
use File::Find;
use XML::Writer;

use vars qw(@ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(SetRequestedType GenerateXml);

my $group_name = "";
my $file_type = "";
my $ext = "";
my $writer = "";

sub SetRequestedType
{
    $group_name = shift;
    $file_type = shift;
    $ext = shift;
}

sub wanted
{
    if ($File::Find::name =~ /\.$ext$/)
    {
        $writer->startTag($file_type);
        $writer->startTag('big_url');
        $writer->characters($File::Find::name);
        $writer->endTag();
        $writer->endTag();
    }    
}

sub GenerateXml
{
    my $filename = shift;
    my $directory = shift;

    my $output = new IO::File(">$filename");
    $writer = new XML::Writer( OUTPUT => $output );

    $writer->xmlDecl( 'UTF-8' );
    $writer->startTag( $group_name, 'xmlns' => 'http://mydomain.com/'.$group_name, 
                        'version' => '1.0' );
    find(\&wanted, $directory);
    $writer->endTag();  
}

package main;

FilesToXml::SetRequestedType('docs', 'doc', 'docx');
FilesToXml::GenerateXml("output.xml", ".");

В основном вам нужно вызвать SetRequestedType с типом группы файлов, строка, описывающая одинфайл и расширение файла.Тогда вам просто нужно вызвать GenerateXml с именем выходного файла XML и каталогом для поиска в.

Он работает с использованием ActivePerl в Windows.Может потребоваться незначительная корректировка в других средах.

1 голос
/ 29 января 2011

Не зная Perl и его методов для чтения каталогов или обработки XML это немного псевдокода , который вы можете использовать в качестве шаблона:

strFileExtensionToMap="jpg"
strNodeName="image"
strCollectionName="images"
currentXMLNode=XML.CreateElement(strCollectionName)
StartFolder=Filesystem.GetFolder([however to get folder])
Call RecursiveMapContents(StartFolder)


RecursiveMapContents(folder){
    For each file in folder.Files
    {
        if (file.extension=strFileExtensionToMap)
        xmlFile=XML.CreateElement(strNodeName)
        big_Url=XML.CreateElement("big_url)
        big_url.text=file.path
        xmlFile.AppendChild(big_url)
        currentXMLNode.AppendChild(xmlFile)
    }

    For each subFolder in folder.Folders
    {

        call RecursiveMapContents(subFolder)
    }
}

Конечно, вы можете сделать XML более универсальным, используя тип файла в качестве атрибута элемента файла:

<file type="image"/>

Вы также можете отобразить фактическую структуру вложенных каталогов, используя

<folder name="foldername" path="folderpath"> instead of <images>

Тогда вы могли бы включить текущий folderNode в свой вызов RecursiveMapContents, чтобы в него были вложены файлы и подпапки, что дает вам:

<folder name="foldername" path="folderpath">
    <file type="image">
        <big_url>file path</big_url>
    </file>
    <file type="image">
        <big_url>file path</big_url>
    </file>
    <folder name="foldername" path="folderpath">
        <file type="image">
            <big_url>file path</big_url>
        </file>
        <file type="image">
            <big_url>file path</big_url>
        </file>
    </folder>
</folder>

Я не включил пространства имен, хотя я признаюсь, что был несколько озадачен тем, почему вам нужны отдельные пространства имен для изображений и PDF-файлов. Смысл пространства имен состоит в том, чтобы обеспечить уникальное именование для набора элементов (чтобы чужой элемент изображения не путался с вашим элементом изображения, если вы хотите работать с их XML). Если вам действительно нужно пространство имен вообще, тогда "http://mydomain.com" должно быть достаточно для всех имен ваших элементов. Пространство имен говорит" этот элемент, для которого мы используем сокращенное изображение, на самом деле называется thisnamespace: image ". Так что, если у вас нет двух типов элемент изображения (один в формате PDF, другой в изображениях), и они не эквивалентны, достаточно одного пространства имен.

Также вы можете сделать гораздо больше, чтобы сделать ваш XML более общим и, возможно, менее многословным. В значительной степени каждый, кто разрабатывает формат XML, определяет, должно ли что-то вроде пути к файлу быть атрибутом элемента файла или дочернего элемента (например, вашего big_url), это зависит от того, нужно ли указывать данные (например, filepath = "this filepath "type =" filesystem | http "должен использовать дочерний элемент).

Извините, это не Perl-ответ, но я надеюсь, что это поможет.

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