2012-04-26 9 views
5

डिफ़ॉल्ट रूप से lxml wbr टैग को समझता नहीं है, जो लंबे शब्दों में शब्द-ब्रेक जोड़ने के लिए उपयोग किया जाता है। यह इसे <wbr></wbr> के रूप में स्वरूपित करता है जब इसे बीआर टैग के समान <wbr> के रूप में स्वरूपित किया जाना चाहिए।lxml और <wbr> टैग

मैं इस व्यवहार को lxml में कैसे जोड़ूं?

+1

मुझे आपके आवेदन की जानकारी नहीं है, लेकिन क्या आप आसानी से बंद टैग हटा सकते हैं? –

उत्तर

10

वास्तव में यह पैच libxml2

पहले (यह वाकथ्रू अजगर 2.7.3 के साथ उबंटू 11.04 पर किया गया था) एक परीक्षण कार्यक्रम wbr_test.py परिभाषित करने के लिए मुश्किल नहीं है python wbr_test.py चल रहा है। इसे <\body> से पहले डालना चाहिए, और अंत में not ok प्रिंट करें।

डाउनलोड, निकालने और संकलन libxml2:

wget ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz 
tar xvf libxml2-2.8.0.tar.gz 
cd libxml2-2.8.0/ 
./configure --prefix=/usr 
make -j8 # adjust number to match your number of cores 

स्थापित करें, और अजगर libxml2 बाइंडिंग स्थापित:

sudo make install 
cd to_python_bindings 
sudo python setup.py install 

परीक्षण आपके wbr_test.py एक बार फिर, यकीन है कि यह नवीनतम libxml2 संस्करण के साथ विफल रहता है बनाने के लिए।

पहले HTMLparser.c की एक प्रति बनाएं उदा। /var/tmp में।

अब libxml2 स्रोत के अपूर्ण पर फ़ाइल HTMLparser.c को संपादित करें। forced शब्द (केवल एक घटना) के लिए खोजें। आप <br> टैग परिभाषा पर होंगे। आपको मिली लाइन से शुरू होने वाली तीन पंक्तियों की प्रतिलिपि बनाएँ।सबसे उचित डालने बिंदु अंत से पहले (<var> की परिभाषा के बाद) है। तालिका में अंतिम अल्पविराम प्राप्त करने के लिए केवल '}' के साथ तीन पंक्तियों को डालें, '};' वाला कोई नहीं।

नव डाला कोड में wbr साथ br बदलें और NULL (यह मानते हुए कि एक नए टैग को अनुमति दी गुण नहीं है) करने के लिए DECL clear_attrs बदल जाते हैं।

परिणाम /var/tmp (diff -u HTMLparser.c /var/tmp) में संस्करण के साथ diff चाहिए इस प्रकार है:

@@ -1039,6 +1039,9 @@ 
}, 
{ "var", 0, 0, 0, 0, 0, 0, 1, "instance of a variable or program argument", 
DECL html_inline, NULL, DECL html_attrs, NULL, NULL 
+}, 
+{ "wbr", 0, 2, 2, 1, 0, 0, 1, "possible line break ", 
+ EMPTY , NULL , DECL core_attrs, NULL , NULL 
} 
}; 

मेक और स्थापित:

make && sudo make install 

परीक्षण आपके wbr_test.py एक बार फिर। OK

+0

बहुत अच्छा! क्या आप पुष्टि कर सकते हैं कि रनटाइम कॉन्फ़िगरेशन के साथ समान परिणाम प्राप्त करने का कोई तरीका नहीं है? – bukzor

+0

एक ही प्रश्न के वाक्यांश के लिए एक अलग तरीका: क्या libxml2 उस सूची के रनटाइम कॉन्फ़िगरेशन की अनुमति नहीं देता है जिसे आपने पैच किया है? – bukzor

+0

मैं वास्तव में आश्चर्यचकित हूं कि क्या स्रोत के पुनर्गठन के बिना libxml2 के साथ यह संभव होगा। परिभाषाएं स्थिर स्थिर तत्व तालिका में हैं, जो * अधिक * गतिशील संरचना में प्रतिलिपि नहीं होती है, लेकिन इसका उपयोग इस प्रकार किया जाता है। ऐसी तालिका में प्रविष्टियां जोड़ना सी से संभव नहीं है, इसलिए पायथन से नहीं। – Anthon

3

चूंकि <wbr> केवल HTML5 में मौजूद है, मुझे संदेह है कि सही चीज करने के लिए lxml.html.html5parser का उपयोग करना है।

उस से कम, खाली टैग की सूची नियमित पायथन कोड में परिभाषित की जाती है, ताकि आप हमेशा इसे बंद कर सकें; lxml.html.defs.empty_tags देखें। पैच का स्वागत है, मुझे यकीन है। :)

+0

मैंने बिना किसी प्रभाव के बंदरपैचिंग की कोशिश की है। – bukzor

+0

@ बुकर: 'br' भी 'special_inline_tags' में है ... आपको उसमें' wbr 'बंदरपैच करने की आवश्यकता हो सकती है। –

+1

आपको पहले 'defs' आयात करना होगा और lxml में कुछ और आयात करने से पहले इसे बंद कर देना होगा, या अन्य मॉड्यूल पुराने मान आयात करेंगे। – Eevee

5

अच्छी खबर! यह पूरी तरह असंभव है। एचटीएमएल टैग नाम baked right into libxml2 हैं।

और lxml.html.html5parser में कुछ गंभीर बग शामिल हैं जिनके फ़िक्स ने अभी तक इसे रिलीज़ नहीं किया है।

लेकिन बिल्ली, चलो उन्हें स्थानीय रूप से ठीक करें और देखें कि क्या होता है।

>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>'), encoding=unicode) 
u'<html:p xmlns:html="http://www.w3.org/1999/xhtml">hello<html:wbr></html:wbr>world!</html:p>' 

तो बंद करें, और अभी तक अभी तक। संरचना कम से कम सही है।

एक और कोशिश:

>>> lxml.html.tostring(lxml.html.html5parser.fromstring('<p>hello<wbr>world!</p>', parser=lxml.html.html5parser.HTMLParser(namespaceHTMLElements=False)), encoding=unicode) 
u'<p>hello<wbr></wbr>world!</p>' 

Welp।

यह गलत कम से कम नहीं है।

मुझे लगता है कि मैं lxml और libxml2 के खिलाफ कुछ बग फ़ाइल कर सकता हूं।

from lxml import etree 
from cStringIO import StringIO 

wbr_html = """\ 
<html> 
    <head> 
    <title>wbr test</title> 
    </head> 
<body> 
    Test for a breakable<wbr>word implemenation change 
</body> 
</html> 
""" 

parser = etree.HTMLParser() 
tree = etree.parse(StringIO(wbr_html), parser) 

result = etree.tostring(tree.getroot(), 
         pretty_print=True, method="html") 
if result.split() != wbr_html.split(): # split, as we are not interested in whitespace differences 
    print(result) 
    print("not ok") 
else: 
    print("OK") 

यकीन है कि यह द्वारा विफल रहता है बनाओ:

1

त्वरित सुधार के रूप में, बंद टैग को हटाने के लिए replace तारों की विधि का उपयोग क्यों न करें?

>>> t = 'Thisisa<wbr></wbr>test' 
>>> t.replace('</wbr>', '') 
'Thisisa<wbr>test'