HTML innerhalb Knoten mit ElementTree
-
23-08-2019 - |
Frage
Ich verwende ElementTree eine XML-Datei zu analysieren. In einigen Bereichen wird es HTML-Daten sein. Betrachten wir zum Beispiel eine Erklärung wie folgt:
<Course>
<Description>Line 1<br />Line 2</Description>
</Course>
Nun _course Annahme ist ein Element Variable, die dieses Element Couse halten. Ich mag diesen Kurs Beschreibung zuzugreifen, so dass ich tun:
desc = _course.find("Description").text;
Aber dann ab enthält nur „Linie 1“. Ich las etwas über das .tail Attribut, also versuchte ich auch:
desc = _course.find("Description").tail;
Und ich bekomme die gleiche Leistung. Was soll ich tun, um desc seine „Linie 1 | Zeile 2“ (oder buchstäblich alles zwischen und) zu machen? Mit anderen Worten, ich bin auf der Suche nach etwas ähnlich der .innerText Eigenschaft in C # (und vielen anderen Sprachen, die ich denke).
Lösung
Haben Sie eine Kontrolle über die Erstellung der XML-Datei? Der Inhalt von XML-Tags, die XML-Tags (oder ähnliche) enthalten, oder Markup-Zeichen ( ‚<
‘, usw.) sollte dieses Problem zu vermeiden codiert werden. Sie können dies entweder mit:
- CDATA Abschnitt
- Base64 oder eine andere Codierung (das ist xml reservierte Zeichen nicht)
- Entity-Codierung ( '
<
'==
'<
')
Wenn Sie nicht diese Änderungen vornehmen können, und ElementTree können momentan keine Tags ignorieren nicht im XML-Schema enthalten, dann werden Sie vorverarbeitet, haben Sie die Datei. Natürlich bist du kein Glück, wenn das Schema html überlappt.
Andere Tipps
Sie versuchen das Schwanz-Attribut aus dem falschen Elemente zu lesen. Versuchen
desc = _course.find("br").tail;
Das Schwanz-Attribut wird verwendet, um Text-Knoten zu speichern Hinter wenn gemischten Inhalt XML-Dateien zu lesen; Text, der direkt nach einem Elemente folgt ist im Heck Attribute für das Element gespeichert:
<tag><elem>this goes into elem's text attribute</elem>this goes into elem's tail attribute</tag>
Einfacher Code-Schnipsel drucken Text und Schwanz Attribute von allen Elementen in XML / XHTML.
import xml.etree.ElementTree as ET def processElem(elem): if elem.text is not None: print elem.text for child in elem: processElem(child) if child.tail is not None: print child.tail xml = '''<Course> <Description>Line 1<br />Line 2 <span>child text </span>child tail</Description> </Course>''' root = ET.fromstring(xml) processElem(root)
Ausgabe:
Line 1 Line 2 child text child tail
Siehe http://code.activestate.com/recipes/498286- elementtree-text-Helfer / für eine bessere Lösung. Es kann geändert werden, gerecht zu werden.
P. S. Ich änderte meinen Namen von user839338 wie im nächsten Post zitiert
Charaktere wie "<" und "&" ist illegal in XML-Elementen.
„<“ wird ein Fehler generiert, da der Parser es als Beginn eines neuen Elements interpretiert.
„&“ wird ein Fehler generiert, da der Parser es als Beginn einer Entity interpretiert.
Ein Text, wie JavaScript-Code enthält eine Menge "<" oder "&" Zeichen. Um Fehler zu vermeiden, Script-Code kann als CDATA definiert werden.
Alles in einem CDATA-Abschnitt vom Parser ignoriert wird.
Ein CDATA-Abschnitt beginnt mit "":
Weitere Informationen unter: http://www.w3schools.com/xmL/xml_cdata.asp
Hope, das hilft!
Inspiriert von user839338 Antwort , ich wen't und sah für eine vernünftige Lösung, die ein bisschen wie folgt aussieht.
>>> from xml.etree import ElementTree as etree
>>> corpus = '''<Course>
... <Description>Line 1<br />Line 2</Description>
... </Course>'''
>>>
>>> doc = etree.fromstring(corpus)
>>> desc = doc.find("Description")
>>> desc.tag = 'html'
>>> etree.tostring(desc)
'<html>Line 1<br/>Line 2</html>\n'
>>>
Es gibt keinen einfachen Weg, um den umliegenden Tag (ursprünglich <Description>
) zu beseitigen, aber es ist leicht in etwas geändert, die bei Bedarf verwendet werden könnte, zum Beispiel <div>
oder <span>