[英]How do I get the full XML or HTML content of an element using ElementTree?
也就是说,所有的文本和子标签,没有元素本身的标签?
拥有
<p>blah <b>bleh</b> blih</p>
我要
blah <b>bleh</b> blih
element.text 返回 "blah " 和 etree.tostring(element) 返回:
<p>blah <b>bleh</b> blih</p>
ElementTree 完美运行,您必须自己组装答案。 像这样的东西...
"".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )
感谢 JV amd 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'
>>>
不需要尾巴。
这是我最终使用的解决方案:
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += etree.tostring(sub_element)
s += element.tail
return s
这些是很好的答案,可以回答 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 ))
要获取有关原始文本之间边界的所有详细信息:
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 )
LibreOffice Writer 文档(.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 字符。
当然,这种讨论越不以“以英语为中心”,其微妙之处和复杂性就越大!
我怀疑 ElementTree 是否适合用于此目的。 但是假设您有充分的理由使用它,也许您可以尝试从片段中剥离根标记:
re.sub(r'(^<%s\b.*?>|</%s\b.*?>$)' % (element.tag, element.tag), '', ElementTree.tostring(element))
这里的大多数答案都基于 XML 解析器ElementTree
,即使是PEZ 的基于正则表达式的答案仍然部分依赖于 ElementTree。
所有这些都很好并且适用于大多数用例,但是,为了完整性,值得注意的是, ElementTree.tostring(...)
将为您提供等效的代码段,但并不总是与原始有效负载相同。 如果出于某种非常罕见的原因,您想按原样提取内容,则必须使用基于正则表达式的纯解决方案。 这个例子是我如何使用基于正则表达式的解决方案。
这个答案稍微修改了Pupeno 的回复。 在这里,我将编码类型添加到“tostring”中。 这个问题花了我很多小时。 我希望这个小小的更正能帮助其他人。
def element_to_string(element):
s = element.text or ""
for sub_element in element:
s += ElementTree.tostring(sub_element, encoding='unicode')
s += element.tail
return s
不知道是否可以选择外部库,但无论如何 - 假设页面上有一个带有此文本的<p>
,jQuery 解决方案将是:
alert($('p').html()); // returns blah <b>bleh</b> blih
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.