那是相當容易lxml *,使用parse()
和tostring()
功能:
from lxml.etree import parse, tostring
首先,解析文檔,讓你的元素(我使用XPath,但你可以使用任何你想要的):
doc = parse('test.xml')
element = doc.xpath('//text')[0]
的tostring()
函數返回的元素的文本表示:
>>> tostring(element)
'<text>Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
然而,你不希望外部因素,所以我們可以用一個簡單的str.replace()
調用其刪除:
>>> tostring(element).replace('<%s>'%element.tag, '', 1)
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
注意str.replace()
收到1作爲第三個參數,因此它只會移除第一次出現的開標籤。也可以用結束標籤來完成。現在,而不是1,我們通過-1來代替:
>>> tostring(element).replace('</%s>'%element.tag, '', -1)
'<text>Some <text>text with <extradata>data</extradata> in it.\n'
的解決方案,當然,是在一次做的一切:
>>> tostring(element).replace('<%s>'%element.tag, '', 1).replace('</%s>'%element.tag, '', -1)
'Some <text>text with <extradata>data</extradata> in it.\n'
編輯:@Charles取得了良好的點:這個代碼很脆弱,因爲標籤可以有屬性。一種可能的,但仍有限的解決方案是拆分在第一>
字符串:
>>> tostring(element).split('>', 1)
['<text',
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n']
獲得第二生成的字符串:
>>> tostring(element).split('>', 1)[1]
'Some <text>text</text> with <extradata>data</extradata> in it.</text>\n'
然後rsplitting它:
>>> tostring(element).split('>', 1)[1].rsplit('</', 1)
['Some <text>text</text> with <extradata>data</extradata> in it.', 'text>\n']
,並終於得到第一個結果:
>>> tostring(element).split('>', 1)[1].rsplit('</', 1)[0]
'Some <text>text</text> with <extradata>data</extradata> in it.'
儘管如此,這個代碼仍然很脆弱,因爲>
是XML中完全有效的字符,甚至是屬性內部的字符。我不得不承認MattH solution是真正的通用解決方案。
*實際上,該解決方案也適用於ElementTree,如果您不想依賴lxml,這種方法非常好。唯一的區別是你將無法使用XPath。
OP想要獲取特定元素的內容。在這種情況下,您的解決方案不起作用,至少不是直接。 II得到一個帶有e = t.xpath('// text')[0]'的元素並試過('''.join(map(etree.tostring,e))'),但結果是'其中有數據 。 –
brandizzi
@brandizzi好點。更新以反映這一點。 – Marcin
需要測試一些更多的案例,但你的最後一個例子對我來說工作得很好(到目前爲止)。當使用'find'而不是'xpath'時,它也可以與標準的''etree''一起使用。 – Brutus