Задачка на автоматизацию и сообразительность...
На пример, имеем документ
[html]
<html>
<header>
</header>
<body>
Text text text
<a>Ref</a>
</body>
</html>
[/html]
Понятно, что вставлять можем только в тело <body>, причем ссылка в ссылке не допустима, поэтому в <a></a> вставлять нельзя. Получается что можем вставить в места отмеченные решеткой:
[html]
<body>
#Text# text# text#
<a>Ref</a>#
</body>
[/html]
Нужен общий алгоритм. Есть всякие грабли, например <table><tr><td>, где вставлять можно только в <td>.
Так вот, подход был следующий - был класс "парсер" котрый бегал по страничке и выкусывал инфу а его функции GetText, GetDate, GetLink перезагружались в "скриптах".
"Скрипт"- был c# файл который содержал класс-наследника данного парсера в котором были как раз установлены начиная с каких тэгов и по какие надо вычитывать и иногда перезагружен сам механизм чтения(скажем скип определенных тэгов, инкрементация ссылок днями недели а не +1 и тд). Этих скриптов было по количеству сайтов, не могу сказать что все работало хорошо но ИМХО принцип верный.
Те в твоей задаче тоже - есть набор тегов (<body>) куда по умолчанию можно вставлять ссылки. Набор задает программист. Потом для каждого такого блока (если он есть) вставляем ссылку один раз (например в конце перед закрывающим тегом) Задача сводится к тому чтобы не вставить ссылку в ссылку. При однократном проходе такое по-идее не возникнет. При многократном - вычитываем весь текст со ссылками в строку и смотрим на субстринг (проверяем наличие <a>..<a>). всё.
ps: Очень рад тебя видеть. Когда я только начинал я многому научился из твоих и ЗАЗ- овских постов.
- Используя любой готовый парсер, разбиваем документ на дерево тегов
- Выполняем обход по тегам. Если тег входит в список разрешенных (или не входит в список запрещенных), разбираем его содержимое на слова, вставляя между ними ссылки
- Используя любой готовый парсер, разбиваем документ на дерево тегов
- Выполняем обход по тегам. Если тег входит в список разрешенных (или не входит в список запрещенных), разбираем его содержимое на слова, вставляя между ними ссылки
В принципе верно, но очень упрощенно. Упущены важные моменты:
1. Весь набор тегов должен быть разбит на 3 части:
- "отсекающие" - отсекают необходимость дальнейшей рекурсии по ветке (A, SCRIPT, HEADER и т.п.)
- "пропускающие" - в них нельзя вставлять, но у них могут быть вложенные теги, в которые вставлять можно (TABLE, HTML, TR и т.п.)
- "разрешающие" - в текст которых вставлять можно, но только в текст, а ведь внутри могут быть ещё и вложенные теги всех трех групп.
2. DOM-парсер должен иметь возможность предоставления инф. о положении тега в исходном файле.
Может кто-то предложит, как решить задачу с помощью SAX-парсера?
1. Весь набор тегов должен быть разбит на 3 части:
- "отсекающие" - отсекают необходимость дальнейшей рекурсии по ветке (A, SCRIPT, HEADER и т.п.)
- "пропускающие" - в них нельзя вставлять, но у них могут быть вложенные теги, в которые вставлять можно (TABLE, HTML, TR и т.п.)
- "разрешающие" - в текст которых вставлять можно, но только в текст, а ведь внутри могут быть ещё и вложенные теги всех трех групп.
2. DOM-парсер должен иметь возможность предоставления инф. о положении тега в исходном файле.
Может кто-то предложит, как решить задачу с помощью SAX-парсера?
А для чего нужно решать с помощью SAX? SAX обычно используется для оптимизации потребления памяти при работе с большими XML документами, если ты работаешь с HTML документами, то это скорее всего веб страницы, для чего нужен SAX?
Основная проблема будет в том, что сакс как таковой не умеет менять структуру документа, следовательно, придется эти метки "решетки" ставить в "копию" документа, которая генерится по мере прохода парсера.
Подход примерно такой:
- Пишется обычный SAX parser callback class, который хранит в себе список разрешающих тегов, в которые можно добавлять. Остальные нас тутне интересуют.
- В большинстве callback-методов просто осуществляется формирование копии документа "как есть".
- В методах типа startElement , проверяется тег. Если он входит в список "разрешающих" - у класса коллбека ставится статус, типа - "в данный момент мы внутри тега, куда можно вставить ссылку".
- в том startElement далее по коду делаем вторую проверку.
ЕСЛИ это текстовый элемент И мы внутри разрешающего тега - ТОГДА разбираем текст внутри определенным способом.
Как-то так.
Принципиальные вопросы - зачем тут вообще сакс, а если он нужен, то как создавать на лету копию документа.
Может кто-то предложит, как решить задачу с помощью SAX-парсера?
Вообще SAX это достаточно ограниченная по применимости штука (строить автоматы состояний както не сильно здорово).
И опять же, разве HTML можно разобрать XML парсером? :rolleyes:
Я, вероятно, попробовал использовать классический дотнетный XmlReader (это не SAX и не DOM - это крайне быстрая однопроходная читалка XML структуры, в принципе ей можно читать любой HTML) с попутным выводом результата XmlWriter-ом, так как задача по видимому спокойно решается в однопроходном режиме.
SAX парсеры сами управляют разбором: генерируют события "тут открывающий тег", "тут атрибут", напротив .NET-ый XmlReader управляется извне - эта стратегия мощнее. Здесь подробнее.