Убрать тег, оставить его содержимое (unwrap)

118
25 мая 2019, 14:40

Код на Ruby использует Nokogiri, обрабатывает HTML. Нужно удалить лишние <div class="section">, оставив их содержимое. Структура такая:

<div class="section" id="a">
    <p>content</p>
    <div class="section" id="b">
        <p>content</p>
    </div>
    <div class="section" id="c">
        <p>content</p>
    </div>
    <div class="section" id="d">
        <p>content</p>
    </div>
</div>

Пробовал два варианта:

@html.xpath("//div[@class = 'section']").each do |div|
  div.parent.inner_html = div.inner_html unless div.parent.nil?
end
@html.xpath("//div[@class = 'section']").each do |div|
  div.replace(div.inner_html)
end

В обоих случаях удаляется только внешний <div class="section">, а вложенные остаются. Смотрел в логи: селектор Xpath находит все эти дивы, не только вложенный. Соответственно, и цикл проходит по всем.

Подозреваю, что после того, как заменяется первый <div>, дерево его содержимого выстраивается заново из div.inner_html. Поэтому остальные дивы уже находятся не в этом дереве, так что их замена ничего не даёт.

Вопрос: как заменить все?

Дополнительный вопрос: объясните, как именно происходит замена, почему вложенные дивы не заменяются?

Answer 1

Можно сделать внешний цикл, который будет повторять итератор @html.xpath("//div[@class = 'section']").each до тех пор, пока он будет осуществлять хоть бы одну замену за проход. Соответственно, после каждого прохода внешнего цикла, итератор @html.xpath("//div[@class = 'section']").each будет находить всё более вложенные элементы, пока не исчерпается вложенность.

Кроме того, можно ограничиться изменением одного элемента за один проход внешнего цикла, выполняя выход из внутреннего итератора во внешний цикл после каждой успешной замены первого найденного элемента (тем самым пересоздавая внутренний итератор на основании измененной иерархии). При таком подходе можно пойти дальше и вообще отказаться от внутреннего итератора, заменив его на вызов at_xpath, который сразу же возвращает один найденный элемент.

READ ALSO
css calc() не работает [закрыт]

css calc() не работает [закрыт]

Подскажите где ошибка в выражении

115
Не обращать внимание на радиобаттоны

Не обращать внимание на радиобаттоны

Помогите, пожалуйста, в таком вопросе

142
Не работает Button jquey в Mozila

Не работает Button jquey в Mozila

В хроме button работаетВ мозиле не хочет

171
Индекс находился вне границ массива, с#

Индекс находился вне границ массива, с#

Ошибку выдает на строчке: max[m] = max[m] + C[i, j]

142