Парсер для обработки тагов

Тема в разделе "PHP программирование", создана пользователем Deadangel, 27 окт 2007.

Статус темы:
Закрыта.
  1. Deadangel

    Deadangel Гость

    Всем привет,

    прошу Вас помочь в одной деликатной ситуации. Ситуация такая:

    есть некоторый текст из N символов. В этом тексте содержатся разные таги (<table>, <tr>, <td>, <img>, <a>). Нужно этот текст разделить на несколько равных частей, т.е сделать постраничный вывод для этого текста. Возникают такие ситуации, когда при разделении текста половина тага находится в одной части, другая половина находится в другой. Чтобы этого избежать, нужно обрабатывать эти таги. Может быть кто-нибудь подскажет, есть ли готовые решения подобных парсеров или же может кто делал что-то подобное. Буду признателен за любую информацию.


    Спасибо.
     
  2. MajestiC

    MajestiC Гость

    Первое что взбрело в голову (слишком много ограничений, наверное не подойдет):

    Для начала делаешь так, чтобы участки (слова/тэги) разделенные пробелами/табуляциями не резались прямо в слове, и что-бы таблицы/ссылки не разрывались (то есть, если на странице есть таблица или ссылка, то таблица/ссылка не перескакивает частично на след. страницу). Реализовать это можно регулярками. Так вот делишь части.

    Потом обрабатываешь (на-лету при выводе, или заранее):
    Первая страница - ты должен закрыть все открытые тэги для корректного вывода:
    Код (Text):
        function closeTags($html)
    {
    #put all opened tags into an array
    preg_match_all("#<([a-z]+)( .*)?(?!/)>#iU",$html,$result);
    $openedtags=$result[1];

    #put all closed tags into an array
    preg_match_all("#</([a-z]+)>#iU",$html,$result);
    $closedtags=$result[1];
    $len_opened = count($openedtags);
    # all tags are closed
    if (count($closedtags) == $len_opened)
    return $html;

    $openedtags = array_reverse($openedtags);
    # close tags
    for($i=0;$i < $len_opened;$i++)
    {
    if ($openedtags[$i] != 'hr' && $openedtags[$i] != 'br' && $openedtags[$i] != 'img')
    {
    if (!in_array($openedtags[$i],$closedtags))
    {
    $html .= '</'.$openedtags[$i].'>';
    }
    else
    {
    unset($closedtags[array_search($openedtags[$i],$closedtags)]);
    }
    }
    }
    return $html;
    }
    Функция конечно не сильно универсальна (лень было искать одиночные теги), но должна сработать =)
    Потом по аналогии с ней делаешь функцию openTags который открывает закрытые (но не открытые) тэги.

    В последующих страницах делаешь openTags, потом closeTags.

    Как-то так. Может кто что-нибудь по-оригинальней придумает, но мне в данный момент лень :)
     
  3. Deadangel

    Deadangel Гость

    Вот, например, текст на входе такой:

    $html = '<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center"><tr><td><p>Уважаемые абоненты,
    Предлагаем Вам воспользоваться услугой <b>"КОММУТИРУЕМЫЙ ДОСТУП В ИНТЕРНЕТ"</b> с использованием модемного пула 600-7000, число соединительных линий на котором увеличено до 6800.
    За счёт хорошей связи модемного пула 600-7000 со всеми узлами Городской Телефонной Сети качество соединений существенно возрастет, а мощности нового модемного пула позволят обеспечить устойчивое подключение всех абонентов компании "КОМСТАР-Директ", пользующихся коммутируемым доступом.<p><img src="../ads.jpg" alt="" width="758" height="535" border="0"></p>
    В целях работоспособности услуг: обратный вызов (call-back), дополнительные входные имена, а также для доступа абонентов из Московской области будут сохранены номера модемных пулов 105-5555, 995-5555 и 995-5556.</p></td></tr></table><table width="100%" border="0" cellspacing="0" cellpadding="0" align="center"><tr><td><p><img src="../ads.jpg" alt="" width="758" height="535" border="0"></p><p>Уважаемые абоненты,
    Предлагаем Вам воспользоваться услугой <b>"КОММУТИРУЕМЫЙ ДОСТУП В ИНТЕРНЕТ"</b> с использованием модемного пула 600-7000, число соединительных линий на котором увеличено до 6800.
    За счёт хорошей связи модемного пула 600-7000 со всеми узлами Городской Телефонной Сети качество соединений существенно возрастет, а мощности нового модемного пула позволят обеспечить устойчивое подключение всех абонентов компании "КОМСТАР-Директ", пользующихся коммутируемым доступом.
    В целях работоспособности услуг: обратный вызов (call-back), дополнительные входные имена, а также для доступа абонентов из Московской области будут сохранены номера модемных пулов 105-5555, 995-5555 и 995-5556.</p></td></tr></table>';

    При первом вырезании попадаем в тег <img> и получаем вот что:

    $text = '<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center"><tr><td><p>Уважаемые абоненты,
    Предлагаем Вам воспользоваться услугой <b>"КОММУТИРУЕМЫЙ ДОСТУП В ИНТЕРНЕТ"</b> с использованием модемного пула 600-7000, число соединительных линий на котором увеличено до 6800.
    За счёт хорошей связи модемного пула 600-7000 со всеми узлами Городской Телефонной Сети качество соединений существенно возрастет, а мощности нового модемного пула позволят обеспечить устойчивое подключение всех абонентов компании "КОМСТАР-Директ", пользующихся коммутируемым доступом.<p><img src="../ads.jpg" alt="" ';

    И как быть дальше ? Как искать теги ?
     
  4. progstone

    progstone Гость

    если в тексте нету тега script то вполне можно считать тагом от '<' и до '>'
     
  5. Deadangel

    Deadangel Гость

    А если в самом тексте встречаются символы? (<, >, <<, >> ...)
     
  6. progstone

    progstone Гость

    значит обрабатывай в 2 этапа,
    1)просто выделяй в динамически разрастаемый массив теги как от '<' до '>'(для надежности пропускай "<<" и ">>")
    2)из полученных тегов определяй какие изи них действимтельно теги(понапиши всякие в блокноте и посмотри как ихи интерпретирует IE)
    P.S сам уже такое реализовывал на Visual C++,пытался писать качалку сайтов.Нормально парсило html,но вот между тегами <script></script><noscript> пришлдось просто пропускать,а с современным подходом к сайто строительству ето не дело.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей