如何使用ElementTree获取元素的完整XML或HTML内容?

2024-10-01 04:58:49 发布

您现在位置:Python中文网/ 问答频道 /正文

也就是说,所有文本和子标记,没有元素本身的标记?

拥有

<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>

Tags: text标记文本元素elementetreeblahblih
3条回答

ElementTree工作得很好,你必须自己组装答案。像这样的。。。

"".join( [ "" if t.text is None else t.text ] + [ xml.tostring(e) for e in t.getchildren() ] )

感谢合资公司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'
>>> 

不需要尾巴。

这些都是很好的答案,它们回答了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 doc(.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: |
   |)

关于混乱的一点是,对于文本样式何时指示单词边界以及何时不指示:紧跟在单词后面的上标(没有空格)在我可以想象的所有用例中都意味着一个单独的单词,没有硬性规定。有时,你可能会发现,例如,一个文档中的第一个字母由于某种原因被加粗,或者第一个字母可能使用不同的样式来表示为大写,而不是简单地使用普通的UC字符。

当然,这种讨论的“以英语为中心”越少,其微妙之处和复杂性就越大!

这是我最终使用的解决方案:

def element_to_string(element):
    s = element.text or ""
    for sub_element in element:
        s += etree.tostring(sub_element)
    s += element.tail
    return s

相关问题 更多 >