Frage

Das heißt, alle Texte und Unter-Tags, ohne den Tag eines Elements selbst?

Mit

<p>blah <b>bleh</b> blih</p>

Ich will

blah <b>bleh</b> blih

element.text returns "blah" und etree.tostring (Element) zurück:

<p>blah <b>bleh</b> blih</p>
War es hilfreich?

Lösung 2

Dies ist die Lösung, die ich am Ende mit:

def element_to_string(element):
    s = element.text or ""
    for sub_element in element:
        s += etree.tostring(sub_element)
    s += element.tail
    return s

Andere Tipps

ElementTree perfekt funktioniert, müssen Sie sich selbst die Antwort montieren. So etwas wie dies ...

"".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )

Dank JV amd PEZ die Fehler für den Hinweis auf.


Bearbeiten.

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

Schwanz nicht benötigt wird.

Das sind gute Antworten, die die OP der Frage zu beantworten, vor allem, wenn die Frage auf HTML beschränkt ist. Aber Dokumente sind von Natur aus chaotisch, und die Tiefe des Elements Verschachtelung ist in der Regel unmöglich, vorherzusagen.

Zur Simulation DOM getTextContent () Sie hätte eine (sehr) einfache rekursive Mechanismus verwenden.

Um nur den nackten Text zu erhalten:

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

Um alle Details über die Grenzen zwischen den Rohtext zu bekommen:

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 )

Beispiel Ausgabe von Einzel para in Libreoffice Writer doc (.fodt Datei):

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

Einer der Punkte, über Unsauberkeit ist, dass es keine harte und schnelle Regel etwa, wenn ein Textstil zeigt eine Wortgrenze, und wenn es tat: Exponent sofort ein Wort folgenden (ohne Leerzeichen) bedeutet ein separates Wort in jedem Gebrauch Fälle kann ich mir vorstellen. OTOH manchmal finden Sie vielleicht, zum Beispiel ein Dokument, in dem der erste Buchstabe entweder aus irgendeinem Grund bolded ist, oder vielleicht verwendet einen anderen Stil für den ersten Buchstaben als Großbuchstaben darstellen, anstatt einfach nur die normale UC Zeichen.

Und natürlich die weniger in erster Linie „Englisch-centric“ diese Diskussion wird desto größer ist die Feinheiten und Komplexitäten!

Ich bezweifle ElementTree die Sache ist für diesen Einsatz. Aber angenommen, Sie haben gute Gründe für die Verwendung es vielleicht könnten Sie versuchen, die Wurzel-Tag aus dem Fragment Strippen:

 re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))

Die meisten Antworten hier sind auf dem XML-Parser ElementTree basiert, auch PEZ regex-basierte Antwort noch beruht teilweise auf ElementTree.

Alle, sind gut und geeignet für die meisten Anwendungsfälle, sondern nur aus Gründen der Vollständigkeit ist es erwähnenswert, dass, ElementTree.tostring(...) gibt Ihnen einen gleichwertigen Schnipsel, aber nicht immer identisch mit der ursprünglichen Nutzlast. Wenn aus irgendeinem Grund sehr selten, dass Sie die Inhalte extrahiert werden soll, wie sie ist, müssen Sie eine reine regex-basierte Lösung verwenden. Dieses Beispiel ist, wie ich regex- basierte Lösung.

Keine Ahnung, ob eine externe Bibliothek könnte eine Option sein, aber trotzdem - vorausgesetzt, es gibt eine <p> mit diesem Text auf der Seite ist, eine jQuery-Lösung sei:

alert($('p').html()); // returns blah <b>bleh</b> blih
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top