那是相当容易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