كيف يمكنني الحصول على XML كامل أو محتوى HTML عنصر باستخدام ElementTree؟
-
22-08-2019 - |
سؤال
وهذا هو، جميع النصوص والعلامات الفرعية، دون علامة عنصر نفسها؟
وبعد
<p>blah <b>bleh</b> blih</p>
وأريد
blah <b>bleh</b> blih
وعوائد element.text "بلاه" وetree.tostring (عنصر) إرجاع:
<p>blah <b>bleh</b> blih</p>
المحلول 2
وهذا هو الحل انتهى بي الأمر باستخدام:
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += etree.tostring(sub_element)
s += element.tail
return s
نصائح أخرى
وElementTree يعمل تماما، لديك لتجميع الجواب بنفسك. شيء من هذا القبيل ...
"".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
وبفضل JV أيه إم دي PEZ لافتا الأخطاء.
وتحرير.
>>> import xml.etree.ElementTree as xml
>>> s= '<p>blah <b>bleh</b> blih</p>\n'
>>> t=xml.fromstring(s)
>>> "".join( [ t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
'blah <b>bleh</b> blih'
>>>
والذيل عدم الحاجة إليها.
وهذه هي الأجوبة الجيدة التي الإجابة على سؤال OP، وخاصة إذا يقتصر السؤال إلى HTML. لكن الوثائق فوضوي بطبيعته، وعمق التعشيش العنصر عادة من المستحيل التنبؤ بها.
لمحاكاة getTextContent DOM () لقد تضطر إلى استخدام آلية متكررة (جدا) بسيطة.
لمجرد الحصول على النص العاري:
def get_deep_text( element ):
text = element.text or ''
for subelement in element:
text += get_deep_text( subelement )
text += element.tail or ''
return text
print( get_deep_text( element_of_interest ))
لتحصل على كل التفاصيل حول الحدود بين النص الخام:
root_el_of_interest.element_count = 0
def get_deep_text_w_boundaries( element, depth = 0 ):
root_el_of_interest.element_count += 1
element_no = root_el_of_interest.element_count
indent = depth * ' '
text1 = '%s(el %d - attribs: %s)\n' % ( indent, element_no, element.attrib, )
text1 += '%s(el %d - text: |%s|)' % ( indent, element_no, element.text or '', )
print( text1 )
for subelement in element:
get_deep_text_w_boundaries( subelement, depth + 1 )
text2 = '%s(el %d - tail: |%s|)' % ( indent, element_no, element.tail or '', )
print( text2 )
get_deep_text_w_boundaries( root_el_of_interest )
والناتج مثال من الفقرة واحدة في ليبر أوفيس الكاتب وثيقة (ملف .fodt):
(el 1 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'Standard'})
(el 1 - text: |Ci-après individuellement la "|)
(el 2 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'T5'})
(el 2 - text: |Partie|)
(el 2 - tail: |" et ensemble les "|)
(el 3 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'T5'})
(el 3 - text: |Parties|)
(el 3 - tail: |", |)
(el 1 - tail: |
|)
واحدة من النقاط حول الفوضى هو أنه لا يوجد قاعدة جامدة وسريعة حول متى يشير إلى نمط النص كلمة الحدود وعندما كان لا: مرتفع مباشرة بعد كلمة (مع عدم وجود المساحة البيضاء) يعني كلمة منفصلة في كل استخدام حالات يمكنني ان اتصور. OTOH في بعض الأحيان قد تجد، على سبيل المثال، وهي وثيقة حيث الحرف الأول هو إما الغامق لسبب ما، أو ربما يستخدم نمط مختلف عن الحرف الأول لتمثيل أنها حالة العلوي، بدلا من مجرد استخدام حرف UC العادي.
وبالطبع أقل في المقام الأول "الإنجليزية التي تركز على" هذا النقاش يحصل على قدر أكبر من الخفايا والتعقيدات!
وأشك ElementTree هو الشيء استخدامه لهذا. ولكن على افتراض لديك أسباب قوية لاستخدامه ربما قد تتمكن من محاولة تجريد العلامة الجذر من جزء:
re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))
وتستند معظم الإجابات هنا على ElementTree
محلل XML، حتى href="https://stackoverflow.com/a/380783/728675"> ما زالت تعتمد جزئيا على ElementTree.
وجميع تلك هي جيدة ومناسبة لمعظم حالات الاستخدام، ولكن فقط من أجل اكتمالها، ومن الجدير بالذكر أن ElementTree.tostring(...)
سوف اعطيكم مقتطف يعادل، ولكن ليست متطابقة دائما إلى حمولة الأصلية. إذا، لسبب نادر جدا، والتي ترغب في استخراج المحتوى كما هو، لديك لاستخدام حل يستند إلى التعابير المنطقية النقي. هذا المثال هو كيف يمكنني استخدام regex- حل قائم.
وأي فكرة إذا مكتبة خارجية قد يكون خيارا، ولكن على أي حال - على افتراض أن هناك <p>
واحد مع هذا النص على الصفحة، ومسج-الحل سيكون:
alert($('p').html()); // returns blah <b>bleh</b> blih