2011-09-19 16 views
11

Mam następujących znaczników HTMLpyton lxml dołączenie elementu po innym elemencie

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

Aby rozwiązać jakiś problem, CSS, chcę dołączyć znacznik div <div style="clear:both"></div> po content_nav div jak to

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

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

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

Robię to w ten sposób:

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>")) 

Ale to nie jest aplikacja koniec nowego div zaraz po content_nav div ale wewnątrz.

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

Czy istnieje jakiś sposób, aby dodać div w środku content_nav div i niektóre p podobnego wewnątrz contents?

Dzięki

+0

CSS tylko rozwiązanie: http://www.quirksmode.org/css/clearing.html –

Odpowiedz

24

Zamiast dołączania do contentnav, iść do rodzica (contentdiv) i insert nowego div w danym indeksie. Aby znaleźć ten indeks, użyj contentdiv.index(contentnav), który daje indeks contentnav w obrębie contentdiv. Dodanie do tego daje pożądany indeks.

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)) 

plony

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

Tak, zrobiłem to samo, po zadaniu pytania. :) –

2

wierzę, że funkcja rodzajowe rozwiązania problemu „insert element po innym elemencie” może być użyteczny, nawet jeśli to tylko przeformułowanie przyjętym odpowiedź:

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

który pozwala wstawić new_element po istniejącym element z zaledwie

insert_after(element, new_element) 
+0

Wszystko, co zrobiłeś, to ponownie zaimplementuj 'element.appendnext()'. – shrewmouse

+0

@ Shrewmouse Chyba masz na myśli 'element.addnext()'. Nie wiem, kiedy został dodany do API, ale teraz jest zdecydowanie najlepszym rozwiązaniem. – mmj

1

Zastosowanie addprevious i addnext dla poprzedzenie i dołączanie rodzeństwa.

Element etree ma dwie metody: addprevious i addnext za wykonanie dokładnie tego, co chcesz.

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)) 

wyjściowa:

<html><body><div id="contents"> 
    <div id="content_nav"> 
     something goes here 
    </div><div style="clear: both"/> 
    <p> 
     some contents 
    </p> 
</div> 
</body></html> 
Powiązane problemy