Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Разбор XML, (ответвление от "Учусь ООП") 
:(
    Опции темы
AndreyCH
Дата 20.3.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.9.2007

Репутация: нет
Всего: нет



Вот для моего класса нужен метод, который распарсит строку и вычленить оттуда название тэга и его значение.
есть 2 метода.
1. файл util.pl
Код

#!/usr/bin/perl 
package UtilXml;
use strict;

sub UtilXml::GetTagData($$){
  my ($val, $tag) = @_;
  my @value = $val =~ m{<$tag>(.+?)</$tag>}gs;
  return @value;
}

sub UtilXml::SaveTagData($$){
  my ($val, $tag) = @_;
  return qq(<$tag>$val</$tag>);
}
1;


2. XML файл, который будем разбирать users.xml
Код

<user_list>
  <user>
    <id>3</id> 
    <name>Sergey</name>
    <lname>Petrov</lname>
  </user>
  <user>
    <id>4</id> 
    <name>Ivan</name>
    <lname>Ivanov</lname>
  </user>
</user_list>


Ну и код которым парсим test.pl
Код

#!/usr/bin/perl 
use strict;
require "util.pl";
open (INFILE, '<users.xml') or die 'cant open file';

undef $/; 

my $cFile = <INFILE>;
my @users;

print "-------------------------\n";

  my $tag = "user_list";
  my @vFile = UtilXml::GetTagData( $cFile, $tag);
  $tag = "user";
  my @users = UtilXml::GetTagData( $vFile[0], $tag);

  foreach my $value (@users){
#   $id=$name=$pass=$value;
    my $tag1 = "name";
    my @vl = UtilXml::GetTagData( $value, $tag1);
    print UtilXml::SaveTagData($vl[0], $tag1),"\n";
  }

close(INPUT);


Это сейчас так работает. А вот это хочу сделать для обучения:
Есть вышеприведенный XML файл. Сразу скажу: "Формирую его только я и никто другой, структура заранее известна и приведена в файле". smile DOM XML, XML::Simple не предлагать я тут учусь регулярным выражениям. smile
Так вот я хочу сделать вот так:
Открыл файл. 
Нашел первый тэг (целое слово внутри угловых скобок). 
Получил имя этого тэга $1. 
Нашел закрывающий тэг $3 (по полученному имени) и все что внутри $2. 
Перешел к обработке второго тэга, третьего и т.д. 
Меня интересует именно "академически" как это сделать внутри одного рег. выражения. Не хотелось бы сначала первым рег. выражением получать первый тэг, затем с помощью GetTagData (см. выше) получать все остальное. 
PM   Вверх
klem4
Дата 20.3.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 27.7.2008

Репутация: 2
Всего: 2



Вам нужно построить деревто чтоли ? Лучьше рекурсивную функцию написать мне кажется чем пытаться регуляркой это сделать. 

Что вы хотите получить регуляркой от такого xml:

Код

<a>
  <b>xx</b>
  <c>
     <d>1</d>
      <d>2</d>
  </c>
</a>


?
PM MAIL   Вверх
KSURi
Дата 20.3.2009, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



AndreyCH, да, вы выбрали неверный метод для изучения регексов


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
AndreyCH
Дата 20.3.2009, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.9.2007

Репутация: нет
Всего: нет



Народ, ну что вы в самом деле! ;-) smile  Я не очень ясно выразил свою мысль. В соседней ветке (Учусь ООП) уже все написано для того, чтобы моя функция вызывалась рекурсивно. Мне нужно по одному уровню дерева пробежаться в XML файле. smile Меня в приведенном примере не устраивает только то, что нужно "из вне" задавать тэг. Если я буду делать все это в регулярном выражении, будет "красивее".
Поясню. На первом проходе обработается только один тэг <user_list>  (он и является единственным элементом массива)во втором проходе обработаем уже только 
Код

  <user>
    <id>3</id> 
    <name>Sergey</name>
    <lname>Petrov</lname>
  </user>
  <list>
    <id>83</id> 
    <frame>back01</frame>
    <frame>back02</frame>
  </list>

соответсвенно все что внутри <user> добавляем в первый элемент нового массива, все что внутри <list> второй
и так далее обрабатываем внутрь. 
Теперь перефразирую вопрос.
Код

$val =~ m{<$tag>(.+?)</$tag>}gs;

где $tag - это собственно и есть название тэга. 
вот как мне написать регулярное выражение чтобы до этой операции находилось название тэга... А уж потом сделолсь тоже что и в приведенном примере. И все это внутри одного регэкспа.
PS а вот тут уже можно и регэкспам поучиться. smile
PM   Вверх
KSURi
Дата 20.3.2009, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Код

$val =~ /<(.+?)>(.+?)<\1>/

В $2 окажутся данные из тэга

Добавлено через 1 минуту и 54 секунды
Код

my(undef, $data) = $val =~ /<(.+?)>(.+?)<\1>/



--------------------
Died at Life.pl line 21
PM Jabber   Вверх
AndreyCH
Дата 20.3.2009, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 24.9.2007

Репутация: нет
Всего: нет



Ну и умучился я!!! Помощи и разъяснения душа просит!!! smile
итак. xml файли остался прежним - (смотри пред ответ)
Код

#!/usr/bin/perl
use strict;
open (INFILE, '<users.xml') or die 'cant open file';
undef $/;
my $val = <INFILE>;
my($data1, $data2) = $val =~ /<(.+?)>(.+?)<\1>/;
print $data1, " ", $data2, "\n";
close (INFILE);

и$data1 и$data2 undef и я код так мучил и по-другому и вот до чего дошел если меняем регулярку на
Код

my($data1) = $val =~ /<(.+?)>/;

на выходе имеем $data1 = "user_list"  как и должно быть. smile
теперь меняем на 
Код

my($data1, $data2) = $val =~ /<(.+?)>(.+?)/;

и оппа!
$data1 = "id" (это-то откуда взялось!!!)
$data2 = "3" (еще одно "чудо в решете")
Народ ну объясните что за... ? smile
Ну и наконец как толко беру  исходное - 
Код
my($data1, $data2) = $val =~ /<(.+?)>(.+?)<\1>/
сразу и$data1 и$data2 undef.
В чем же тут дело?
PM   Вверх
amg
Дата 21.3.2009, 10:08 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Цитата(AndreyCH @  20.3.2009,  22:32 Найти цитируемый пост)
Ну и умучился я!!! Помощи и разъяснения душа просит!!! 
AndreyCH, для начала замените исходную регулярку на логичную для Вашего случая
/<(.+?)>(.+?)<\/\1>/s
и с ней уже экспериментируйте

Цитата(AndreyCH @  20.3.2009,  22:32 Найти цитируемый пост)
В чем же тут дело?
Строка то у Вас многострочная (поэтому нужен модификатор /s), и в закрывающем тэге есть слеш.

Это сообщение отредактировал(а) amg - 21.3.2009, 11:01
PM MAIL   Вверх
SkoobyDoo
Дата 21.3.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 4.10.2007

Репутация: нет
Всего: нет



AndreyCH,
Код

my($data1, $data2) = $val =~ /<(.+?)>(.+?)/;

Код

и оппа!
$data1 = "id" (это-то откуда взялось!!!)
$data2 = "3" (еще одно "чудо в решете")
Народ ну объясните что за... ? smile


регексп поменяйте на 
Код

my ($data1,$data2) = $val =~ m{<([^>]+)>(.+?)</\1>}s;


Это сообщение отредактировал(а) SkoobyDoo - 21.3.2009, 13:35
PM MAIL   Вверх
KSURi
Дата 22.3.2009, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Цитата(amg @  21.3.2009,  10:08 Найти цитируемый пост)
AndreyCH, для начала замените исходную регулярку на логичную для Вашего случая
/<(.+?)>(.+?)<\/\1>/s
и с ней уже экспериментируйте

упс) спасибо за поправку


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0943 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.