كيف يمكنني الحصول على XML كامل أو محتوى HTML عنصر باستخدام ElementTree؟

StackOverflow https://stackoverflow.com/questions/380603

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

وأي فكرة إذا مكتبة خارجية قد يكون خيارا، ولكن على أي حال - على افتراض أن هناك <p> واحد مع هذا النص على الصفحة، ومسج-الحل سيكون:

alert($('p').html()); // returns blah <b>bleh</b> blih
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top