使用lxml *非常容易,使用parse()
andtostring()
函数:
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'
然后将其拆分:
>>> 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 解决方案是真正的通用解决方案。
* 实际上,此解决方案也适用于ElementTree,如果您不想依赖 lxml,这很好。唯一的区别是您将无法使用 XPath。