Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > Perl split


Автор: hausedark 12.7.2016, 00:03
Здравствуйте, помогите с задачей, делаю парсинг дерева категорий: 

Код

my @ar = split(/<category id="/, $c);
    for (my $i=1; $i<@ar; $i++) {
        my ($id, $name) = split(/" parentId="/, $ar[$i]);
        my ($pid, $name) = split(/">/, $name);
        ($name, $chop) = split(/<\/category>/, $name);
        next if ($id == 3811);
        if (($ca{$id} ne "") and ($ARGV[2] eq "update")) {
            print "up $id;$pid;$name;\n";
            &exec_command("update categories set name = \'$name\', pid = \'$pid\' where id = \'$id\';");
        }
        next if ($ca{$id} ne "");
        print "$id;$pid;$name;\n";
        &exec_command("insert into categories (id, name, pid, kolvo) values (\'$id\', \'$name\', \'$pid\', 0);");
    }


Дерево категорий выглядит таким образом и все работает:

Код

<category id="3680259" parentId="0">Футбол,баскетбол</category>
<category id="3680260" parentId="3680259">Футбол</category>
<category id="3680265" parentId="0">Рыбалка</category>
<category id="3680270" parentId="0">Велоспорт</category>
<category id="3680299" parentId="3680260">Сборная</category>


А что если родительский ID нулевой будет отсутствовать, т.е.

Код

<category id="3680259">Футбол,баскетбол</category>
<category id="3680260" parentId="3680259">Футбол</category>
<category id="3680265">Рыбалка</category>
<category id="3680270">Велоспорт</category>
<category id="3680299" parentId="3680260">Сборная</category>


В таком случае данный метод не работает, подскажите как исправить код чтобы при отсутствии parentId="0" в файле в БД писался 0

Автор: igorold 12.7.2016, 06:36
Проверяй переменную $ar[$i] на наличие подстроки 'parentId='
Если подстрока есть, парси, нет - присваивай 0.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Perl-split-id57840a3aae2015385a8b4567#findElement_E7045_578465ceae2015a52e7c7917_0

Автор: hausedark 12.7.2016, 12:35
Подскажите как это в практике будет выглядеть)

Автор: infarch 12.7.2016, 13:04
А почему на парсить XML соответствующими модулями вместо регулярок? Наверно проще будет.

Автор: hausedark 12.7.2016, 13:08
Но медленнее, скорость работы важна) вот придумать не могу как с этим parentId="0" побороться))

Автор: hausedark 12.7.2016, 22:12
Какие будут идеи?) я вообще в панике)) 

Автор: hausedark 13.7.2016, 00:55
Вот полный код:

Код

sub parse_categories {
    my $c = shift;
    
    $c = encode("utf8", decode("utf8", $c));
            
    my %ca = ();
    my $command = "select id from categories;";
    my $q = $dbh->prepare($command);
    $q->execute();
    while (my $r = $q->fetchrow_arrayref) {
        $ca{$$r[0]} = "on";
    }
    
    my @ar = split(/<category id="/, $c);
    for (my $i=1; $i<@ar; $i++) {
        my ($id, $name) = split(/" parent_id="/, $ar[$i]);
        my ($pid, $name) = split(/"><!\[CDATA\[/, $name,);
        ($name, $chop) = split(/\]\]><\/category>/, $name);
        next if ($id == 3811);
        if (($ca{$id} ne "") and ($ARGV[2] eq "update")) {
            print "upd $id;$pid;$name;\n";
            &exec_command("update categories set name = \'$name\', pid = \'$pid\' where id = \'$id\';");
        }
        next if ($ca{$id} ne "");
        print "$id;$pid;$name;\n";
        &exec_command("insert into categories (id, name, pid, kolvo) values (\'$id\', \'$name\', \'$pid\', 0);");
    }
    &update_categories;
}


Не понимаю каким образом при отсутствующем parent_id выполнить запись в БД только в поля Id и name

при первом запуске файла с отсутствующем parent_id в бд запишется все ID и parent_id поле name будет пустым для данных категорий, и при повторном запуске имеем такую ошибку
Код

start parser - 13.7.2016 0:53
236"><![CDATA[Электроника и фото]]></category>
;;;
error = insert into categories (id, name, pid, kolvo) values ('236"><![CDATA[Электроника и фото]]></category>
', '', '', 0);

Автор: igorold 13.7.2016, 08:44
Код

my ($pid,$id,$name) = (0,0,'');
if ($ar[$i] =~ /parent_id=/)
{
    ($id, $name) = split(/" parent_id="/, $ar[$i]);
    ($pid, $name) = split(/"><!\[CDATA\[/, $name,);
    ($name, $chop) = split(/\]\]><\/category>/, $name);
}


Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Perl-split-id57840a3aae2015385a8b4567#findElement_E7045_5785d52bae20154d7e7c77d0_0

Автор: hausedark 13.7.2016, 09:54
Здравствуйте, заменил эту часть кода
Код

my ($id, $name) = split(/" parent_id="/, $ar[$i]);
        my ($pid, $name) = split(/"><!\[CDATA\[/, $name,);
        ($name, $chop) = split(/\]\]><\/category>/, $name);


Вашим, может быть не туда вставляю)) при повторном запуске скрипта ошибка не выскакивает, а просто добавляет 2 пустые строчки в таблицу БД, а этого быть не должно, name по прежнему пустой(

Вот print отработанного скрипта:

Код

248;236;Оптические приборы;
250;236;Dvd и blu-ray плееры;
236"><![CDATA[Электроника и фото]]></category>
;;;
252;236;Портативная аудиотехника;
745;236;Видеокамеры;

Автор: hausedark 13.7.2016, 12:53
2 пустые строчки потому что в XML с отсутствующем  parent_id, 2 строки

Автор: igorold 13.7.2016, 18:34
... блин, а самому подумать не судьба? ... если ты хочешь быть программистом, напряги мозги ... ну всё же очевидно ...

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Perl-split-id57840a3aae2015385a8b4567#findElement_E7045_57865fa3ae2015453a7c7487_0

Автор: hausedark 13.7.2016, 18:46
С Perl только столкнулся, дай подсказку)) чего я не вижу smile 

Автор: hausedark 14.7.2016, 02:50
Мое подумать приводит к такому огромному коду))) а хотелось бы собрать со split

Код

sub parse_categories {

my @arr = localtime(time);
    $arr[4]++;
    $arr[5] =~ s/1/20/;
    local $start_date = "$arr[3].$arr[4].$arr[5] $arr[2]:$arr[1]";
    print "start parser_categories - $start_date\n";
    
    local $dbh = DBI->connect("DBI:mysql:$mysqlbase;$mysqlserver","$mysqluser","$mysqlpassword",{PrintError => 0, RaiseError => 0});
    &exec_command("set names utf8;");

    my %ca = ();
    my $command = "select ind from myshop_categories;";
    my $q = $dbh->prepare($command);
    $q->execute();
    while (my $r = $q->fetchrow_arrayref) {
        $ca{$$r[0]} = "on";
    }
    
    local $dbh = DBI->connect("DBI:mysql:$mysqlbase;$mysqlserver","$mysqluser","$mysqlpassword",{PrintError => 0, RaiseError => 0});
    &exec_command("set names utf8;");
    
    my ($buff,$command,$cur_id);
    my $all_count=0,$cont,$count;
    my $first = 1;    
    my $tag = '<category ';
    my ($el,%cat,$usd);
    
    my $file = "test.xml";
    if (!open (FILE, "$tmp_path/$file")) {
        print "error open file - $tmp_path/$file\n";
        return;
    }

    local $mail = "";
    local ($new, $kolvo) = (0, 0);
    my $categories = "";
    
        my @arr = split($tag,$buff);
        $cont=$tag.(pop @arr) if ($count == 10485760);
        my $first = 1;
        for (my $i=$first; $i<@arr; $i++) {
            $el = $tag.$arr[$i];
            $el = encode("utf8", decode("utf8", $el));
            
            $id = getAttribute('category','id',$el);
            $pid = getAttribute('category','parent_id',$el);

            if (($empty_lines ne '')&&($empty_lines > 0)){
                $empty_lines--;
                next if ($empty_lines > 0);
            }

            $el =~ s/\\//g;

            my $name = getBody('category',$el);        
            next if ($category == 3811);
            
            if (($ca{$id} ne "") and ($ARGV[2] eq "update")) {
            print "upd $id;$pid;$name;\n";
            &exec_command("update categories set name = \'$name\', pid = \'$pid\' where id = \'$id\';");
        }
        next if ($ca{$id} ne "");
        print "$id;$pid;$name;\n";
        &exec_command("insert into categories (id, name, pid, kolvo) values (\'$id\', \'$name\', \'$pid\', 0);");
        }
    
    &update_categories;

Автор: hogo090 21.8.2020, 08:53
Модератор: Сообщение скрыто.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)