如何使用ElementTree获取元素的完整XML或HTML内容?
也就是说,所有的文本和子标签,没有标签本身的元素?如何使用ElementTree获取元素的完整XML或HTML内容?
有
<p>blah <b>bleh</b> blih</p>
我想
blah <b>bleh</b> blih
element.text返回 “嗒嗒” 和etree.tostring(元素)返回:
<p>blah <b>bleh</b> blih</p>
这是我最终使用的解决方案:
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += etree.tostring(sub_element)
s += element.tail
return s
ElementTree的作品完美,你有自己组装答案。像这样的东西...
"".join([ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ])
感谢合资公司和PEZ指出了错误。
编辑。
>>> import xml.etree.ElementTree as xml
>>> s= '<p>blah <b>bleh</b> blih</p>\n'
>>> t=xml.fromstring(s)
>>> "".join([ t.text ] + [ xml.tostring(e) for e in t.getchildren() ])
'blah <b>bleh</b> blih'
>>>
尾巴不需要。
不知道,如果一个外部库可能是一种选择,但无论如何 - 假如有一个<p>
与页面上的这段文字,一个jQuery的解决办法是:
alert($('p').html()); // returns blah <b>bleh</b> blih
我怀疑ElementTree的是为此使用的东西。但是,假设你有使用它,也许你可以尝试从片段剥离根标签有力的理由:
re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))
这些都是很好的答案,这回答OP的问题,特别是如果问题仅限于HTML。但文件本质上是混乱的,元素嵌套的深度通常无法预测。
要模拟DOM的getTextContent(),您必须使用(非常)简单的递归机制。
得到的只是光秃秃的文字:
def get_deep_text(element):
text = element.text or ''
for subelement in element:
text += get_deep_text(subelement)
text += element.tail or ''
return text
print(get_deep_text(element_of_interest))
要获得所有有关原始文本之间的界限的细节:从LibreOffice的作家DOC单对
root_el_of_interest.element_count = 0
def get_deep_text_w_boundaries(element, depth = 0):
root_el_of_interest.element_count += 1
element_no = root_el_of_interest.element_count
indent = depth * ' '
text1 = '%s(el %d - attribs: %s)\n' % (indent, element_no, element.attrib,)
text1 += '%s(el %d - text: |%s|)' % (indent, element_no, element.text or '',)
print(text1)
for subelement in element:
get_deep_text_w_boundaries(subelement, depth + 1)
text2 = '%s(el %d - tail: |%s|)' % (indent, element_no, element.tail or '',)
print(text2)
get_deep_text_w_boundaries(root_el_of_interest)
输出示例(.fodt文件):
(el 1 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'Standard'})
(el 1 - text: |Ci-après individuellement la "|)
(el 2 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'T5'})
(el 2 - text: |Partie|)
(el 2 - tail: |" et ensemble les "|)
(el 3 - attribs: {'{urn:oasis:names:tc:opendocument:xmlns:text:1.0}style-name': 'T5'})
(el 3 - text: |Parties|)
(el 3 - tail: |", |)
(el 1 - tail: |
|)
关于混乱的一点是,没有硬性规定和快速规则关于什么时候文本样式表示一个字的边界,什么时候它没有:立即跟在一个字之后的上标(没有空格)意味着我可以想象的所有用例中的一个单独的字。例如,OTOH有时可能会找到一个文件,其中第一个字母由于某种原因被粗体显示,或者可能对第一个字母使用不同的样式来表示为大写字母,而不是简单地使用普通的UC字符。
当然,主要以“以英语为中心”的这种讨论越来越微妙和复杂!
这里的大部分答案都基于XML解析器ElementTree
,即使PEZ's regex-based answer仍然部分依赖于ElementTree。
所有这些都很好,适合大多数用例,但为了完整起见,值得注意的是,ElementTree.tostring(...)
会给你一个等效的片段,但并不总是与原始有效载荷相同。如果出于某种非常罕见的原因想要按原样提取内容,则必须使用纯正则表达式的解决方案。 This example是我如何使用基于正则表达式的解决方案。
只是指出了一个错字 - 方法名 - 我认为应该是“findall”的“finall”。即使findall被使用,它也会导致这个http://pastebin.com/f6de9a841。请修改你的答案。 – 2008-12-19 11:45:49
@JV:谢谢。固定。 – 2008-12-19 12:19:25