2011-09-19 47 views
11

Tôi có đánh dấu HTML saupython lxml thêm yếu tố sau yếu tố khác

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

Để khắc phục một số vấn đề CSS, tôi muốn thêm một thẻ div <div style="clear:both"></div> sau content_nav div như thế này

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

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

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

Tôi đang thực hiện theo cách này:

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

Nhưng đó không phải ứng dụng kết thúc div mới ngay sau content_nav div nhưng bên trong.

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

Có cách nào để thêm một div ở giữa content_nav div và một số p như thế bên contents?

Cảm ơn

+0

CSS chỉ giải pháp: http://www.quirksmode.org/css/clearing.html –

Trả lời

24

Thay vì phụ thêm để contentnav, đi lên đến phụ huynh (contentdiv) và insert mới div tại một chỉ số cụ thể. Để tìm chỉ mục đó, hãy sử dụng contentdiv.index(contentnav), cung cấp chỉ mục của contentnav trong phạm vi contentdiv. Thêm một vào đó cung cấp cho chỉ mục mong muốn.

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

sản lượng

<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

Yeah, tôi đã làm điều tương tự sau khi đặt câu hỏi. :) –

2

Tôi tin rằng một hàm tổng quát giải quyết các câu hỏi "chèn một phần tử sau khi một yếu tố khác" có thể có ích, ngay cả khi nó chỉ là một xây dựng lại các câu trả lời được chấp nhận:

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

cho phép chèn new_element sau element hiện tại chỉ với

insert_after(element, new_element) 
+0

Tất cả những gì bạn đã làm là triển khai lại 'element.appendnext()'. – shrewmouse

+0

@Shrewmouse Tôi đoán bạn có nghĩa là 'element.addnext()'. Tôi không biết khi nào nó được thêm vào API nhưng bây giờ nó là giải pháp tốt nhất. – mmj

1

Sử dụng addpreviousaddnext cho thêm vào trước và phụ anh chị em.

Phần tử etree có hai phương pháp: addpreviousaddnext để thực hiện chính xác những gì bạn muốn.

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

Output:

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