lexborisov / myhtml

Fast C/C++ HTML 5 Parser. Using threads.
GNU Lesser General Public License v2.1
1.66k stars 147 forks source link

Custom tags in html #174

Closed BartolomeyKant closed 5 years ago

BartolomeyKant commented 5 years ago

Извините, плохо умею в английский. Немного я помучался, и ничего не получилось. Правильно ли я понял, что myhtml плохо работает с не html тегами в html документе. К примеру у меня есть вот такая структура в html документе.

<reporttemplate>
          <query sqltext="SELECT TOP 10 @Number, @Date, @Name, @State From NameStates Where @Date <= @SetDate" >
            <param name = "@Date" substring="Date" type = "DateTime" />
            <param name = "@Name" substring="Value" type = "string" />
            <param name = "@State" substring="State" type = "string" />
            <param name = "@Number" substring="Number" type = "int" />
            <filter name = "@SetDate" substring="10-03-19 13:23:00" type = "DateTime" />
          </query>
          <template>
            <tr>
              <td>@Date</td>
              <td>@Name</td>
              <td>@State</td>
            </tr>
          </template>
        </reporttemplate>

через myhtml_get_nodes_by_name я могу получить элемент в дереве, но например myhtml_node_string(node) - возвращает непонятную строку вида "\n ". То же самое возвращается если попробовать myhtml_serialization_node_callback.

Идея была такая, чтобы получить reporttemplate, пробежаться по его child, и сравнивая теги по имени сделать дальнейшую обработку.

BartolomeyKant commented 5 years ago

Поправка оказывается все работает почти как ожидалось. Вопрос оказался в другом. Написал такую функцию:

// получение имени тега по ноду
QString GetTagName(myhtml_tree_t *tree, myhtml_tree_node_t *node){
     const char *tag_name = myhtml_tag_name_by_id(tree, myhtml_node_tag_id(node), nullptr);
     return tag_name;
}

Если туда передать node, который находится через myhtml_get_nodes_by_name, то все работает как и ожидалось. Но если передать туда его child, то получаем "-text". Теперь вопрос куда указывает node полученный через myhtml_node_child?

lexborisov commented 5 years ago

@Notevill Привет!

Всё верно, функция myhtml_node_child указывает на child. Не забывайте, что пробелы, новые строки и табы всё это тоже нода.

Для примера:

<div>
    <a>text</a>

Итоговое дерево будет такого вида:

<div>
    "\n    "
    <a>
        "text"

То есть, видим, что первый чайлд у ноды div будет текст с новой строкой и пробелами, а второй нода a.

BartolomeyKant commented 5 years ago

Я правильно понимаю, что если перед <a> несколько пробелов, то все они будут отдельными нодами? То есть чтобы добраться от <div> до <a>, нужно получить один child, и несколько раз next? Если использовать MyHTML_TREE_PARSE_FLAGS_SKIP_WHITESPACE_TOKEN, то такой проблемы нет. Но если мы хотим модифицировать html, то на выходе у нас получится человеко-нечитаемый формат?. Эта вещ с распарсиванеим дерева вида

  <div>
    "\n    "
    <a>
        "text"

Не совсем очевидна, почитал другие Issues, и заметил, что у разных людей в разных задачах возникает такая проблема.

lexborisov commented 5 years ago

@Notevill

Я правильно понимаю, что если перед несколько пробелов, то все они будут отдельными нодами?

Нет, не так. Все whitespaces сливаются в одну ноду. То есть, будет одна нода с кучей пробелов.

То есть чтобы добраться от

до , нужно получить один child, и несколько раз next?

Нужно получить один child и сделать один раз next.

то на выходе у нас получится человеко-нечитаемый формат?.

Не уверен, что понимаю вас. Почему модификация HTML должна приводить к нечитабельности?

Если вы хотите "красивую" структуру на выходе то воспользуйтесь новым проектом lexbor там есть режим serialize_pretty. Но помните, данный подход выходит за рамки спецификации.

Не совсем очевидна, почитал другие Issues, и заметил, что у разных людей в разных задачах возникает такая проблема.

Не соглашусь с вами. Это вполне ожидаемое поведение. Тут вопрос к знаниям HTML и его структуре.