web-dev-qa-db-ja.com

python lxml別の要素の後に要素を追加

私は次のHTMLマークアップを持っています

<div id="contents">
    <div id="content_nav">
        something goes here
    </div>
    <p>
        some contents
    </p>   
</div>

CSSの問題を修正するために、このように<div style="clear:both"></div>divの後にdivタグcontent_navを追加したいと思います。

<div id="contents">
    <div id="content_nav">
        something goes here
    </div>

    <div style="clear:both"></div>

    <p>
        some contents
    </p>   
</div>

私はそれをこのようにしています:

import lxml.etree

tree = lxml.etree.fromString(inputString, parser=lxml.etree.HTMLParser())

contentnav = tree.find(".//div[@id='content_nav']")
contentnav.append(lxml.etree.XML("<div style='clear: both'></div>"))

しかし、それはcontent_navdivの直後ではなく内部に新しいdivを追加しません。

<div id="content_nav">
    something goes here
    <div style="clear:both"></div>
</div>

content_navdivの途中にdivを追加し、p内にそのようなcontentsを追加する方法はありますか?

ありがとう

17
Tu Hoang

contentnavに追加する代わりに、特定のインデックスで親(contentdiv)とinsert新しいdivに移動します。そのインデックスを見つけるには、contentdiv.index(contentnav)を使用します。これにより、contentnav内のcontentdivのインデックスが得られます。これに1つ追加すると、目的のインデックスが得られます。

import lxml.etree as ET

content='''\
<div id="contents">
    <div id="content_nav">
        something goes here
    </div>
    <p>
        some contents
    </p>   
</div>
'''
tree = ET.fromstring(content, parser=ET.HTMLParser())
contentnav = tree.find(".//div[@id='content_nav']")
contentdiv = contentnav.getparent()
contentdiv.insert(contentdiv.index(contentnav)+1,
                  ET.XML("<div style='clear: both'></div>"))
print(ET.tostring(tree))

収量

<html><body><div id="contents">
    <div id="content_nav">
        something goes here
    </div>
    <div style="clear: both"/><p>
        some contents
    </p>   
</div></body></html>
32
unutbu

兄弟の追加と追加にはaddpreviousaddnextを使用します。

Etree要素には、addpreviousaddnextの2つのメソッドがあります。

import lxml.etree as ET

content='''\
<div id="contents">
    <div id="content_nav">
        something goes here
    </div>
    <p>
        some contents
    </p>   
</div>
'''
tree = ET.fromstring(content, parser=ET.HTMLParser())
contentnav = tree.find(".//div[@id='content_nav']")
contentnav.addnext(ET.XML("<div style='clear: both'></div>"))
print(ET.tostring(tree))

出力:

<html><body><div id="contents">
    <div id="content_nav">
        something goes here
    </div><div style="clear: both"/>
    <p>
        some contents
    </p>   
</div>
</body></html>
6
shrewmouse

質問に対処する汎用関数"別の要素の後に要素を挿入する"は、受け入れられた回答の単なる再定式化であっても、役立つ可能性があると思います。

def insert_after(element, new_element):
    parent = element.getparent()
    parent.insert(parent.index(element)+1, new_element)

これにより、既存のelementの後にnew_elementを挿入できます。

insert_after(element, new_element)
2
mmj