Python und ElementTree: return „innere XML“ ohne übergeordnetes Element
-
27-09-2019 - |
Frage
In Python 2.6 mit ElementTree, was ist ein guter Weg, um die XML (als String) innerhalb eines bestimmten Elements zu holen, wie das, was Sie tun können, in HTML und JavaScript mit innerHTML
?
Hier ist ein vereinfachtes Beispiel des XML-Knoten, mit denen ich beginne:
<label attr="foo" attr2="bar">This is some text <a href="foo.htm">and a link</a> in embedded HTML</label>
Ich möchte mit dieser Zeichenfolge am Ende:
This is some text <a href="foo.htm">and a link</a> in embedded HTML
Ich habe versucht, den übergeordneten Knoten iterieren und die tostring()
der Kinder verketten, aber das gab mir nur die untergeordneten Knoten:
# returns only subnodes (e.g. <a href="foo.htm">and a link</a>)
''.join([et.tostring(sub, encoding="utf-8") for sub in node])
Ich kann eine Lösung mit regulären Ausdrücken hacken, aber hatte gehofft, es als das etwas weniger hacky würde:
re.sub("</\w+?>\s*?$", "", re.sub("^\s*?<\w*?>", "", et.tostring(node, encoding="utf-8")))
Lösung
Wie wäre:
from xml.etree import ElementTree as ET
xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>'
root = ET.fromstring(xml)
def content(tag):
return tag.text + ''.join(ET.tostring(e) for e in tag)
print content(root)
print content(root.find('child2'))
Resultat:
start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here
here as well<sub2 /><sub3 />
Andere Tipps
Dies ist auf den anderen Lösungen basiert, aber die anderen Lösungen funktionieren nicht in meinem Fall (in Folge Ausnahmen) und dies ist:
from xml.etree import Element, ElementTree
def inner_xml(element: Element):
return (element.text or '') + ''.join(ElementTree.tostring(e, 'unicode') for e in element)
Verwenden Sie es auf die gleiche Weise wie in Mark Tolonen Antwort .
Die folgenden für mich gearbeitet:
from xml.etree import ElementTree as etree
xml = '<root>start here<child1>some text<sub1/>here</child1>and<child2>here as well<sub2/><sub3/></child2>end here</root>'
dom = etree.XML(xml)
(dom.text or '') + ''.join(map(etree.tostring, dom)) + (dom.tail or '')
# 'start here<child1>some text<sub1 />here</child1>and<child2>here as well<sub2 /><sub3 /></child2>end here'
dom.text or ''
wird verwendet, um den Text zu Beginn des root
Elements zu erhalten. Wenn es keinen Text dom.text
ist None
.
Beachten Sie, dass das Ergebnis keine gültige XML -. Eine gültige XML sollte nur ein Wurzelelement haben
Haben Sie einen Blick auf die ElementTree docs über gemischte Inhalte .
Mit Python 2.6.5, Ubuntu 10.04