Манипуляции с DOM в Python (если какой-либо элемент содержит только один другой элемент …)

#python #dom

#python #dom

Вопрос:

Мне нужно удалить все <p> s там, где они не нужны. Например, преобразовать <div><p>xxxx</p></div> в <div>xxxx</div> .

Как я могу это сделать с помощью DOM? «Если <div> внутри есть только один <p> , тогда назначьте этот <p> текст <div> и удалите это <p> «.

Я бы снова сделал это с помощью регулярных выражений, но некоторые люди говорят, что это плохо. Я не могу себе представить, как это делается с помощью DOM.

 text = "<div><p>xxxx</p></div>"
???
  

Возможно ли вообще решить с помощью DOM? Или старое доброе регулярное выражение лучше для этого случая?
Python, а не JavaScript.

Комментарии:

1. Сейчас у меня нет времени, но я думаю, что это вполне возможно для того, что я делал с xml.dom.minidom

Ответ №1:

Это работает для меня:

 from xml.dom import minidom

text = "<div><p>xxxx</p></div>"
doc = minidom.parseString(text)

# For each div in the root document
for tag in doc.childNodes:
    # If it's a <p> and there's only one
    if len(tag.childNodes) == 1 and tag.childNodes[0].tagName == 'p':
        # p_node = <p>xxx</p>
        p_node = tag.childNodes[0]
        # p_text_node = xxx
        p_text_node = p_node.childNodes[0]
        value = p_node.nodeValue
        # Delete the <p>xxx</p>
        p_node.parentNode.removeChild(p_node)
        # Set the <div></div> -> <div>xxx</div>
        tag.appendChild(p_text_node)

print doc.toxml()
  

и выдает:

 <?xml version="1.0" ?><div>xxxx</div>
  

Я надеюсь, что вы примете ответ, который я дал и на ваш другой вопрос, поскольку я проделал всю работу за вас 😉

Ответ №2:

Вот способ, которым вы можете это сделать, используя BeautifulSoup:

 >>> import BeautifulSoup
>>> somehtml = '<html><title>hey</title><body><p>blah</p><div><p>something</p></div></body></html>'
>>> soup = BeautifulSoup.BeautifulSoup(somehtml)
>>> for p in soup.findAll('p'):
...    if p.parent.string is None and len(p.parent.contents) == 1:
...       p.parent.string = p.string
...       p.extract()
>>> soup
<html><title>hey</title><body><p>blah</p><div>something</div></body></html>
  

Выполняется поиск всех <p> элементов, у которых есть родительский элемент без содержимого и только один дочерний элемент ( <p> элемент), затем копирует содержимое <p> элемента в родительский элемент и удаляет <p> элемент.

Комментарии:

1. можем ли мы обновить содержимое HTML (например, манипуляции с DOM) с помощью bs4?

Ответ №3:

Основываясь на ответе @jterrace:

(ПОЖАЛУЙСТА, ОТРЕДАКТИРУЙТЕ ЭТОТ ВОПРОС, ЧТОБЫ ОН БЫЛ ПОЛНЫМ, ИЛИ ПРОКОММЕНТИРУЙТЕ)

Я думаю, что правильный путь — создать a minidom.Document , чтобы вы могли изменять его XML-узлы.

 #coding: utf-8

from xml.dom import minidom

text = "<div><p>xxxx</p></div>"

dom = minidom.parseString(text)

for p in dom.getElementsByTagName('p'):
    print p.childNodes
    # and what now?
  

Ответ №4:

Если у вас есть jquery, это сработает.

 $('div').each(function() {

    if ($(this).children().length > 1)
        return

    if ($(this).children()[0].tagName != "P")
        return

    this.innerHTML = $(this).children()[0].innerHTML;
});