如何将 XML 文档的所有文本内容作为单个字符串获取 -就像这个 Ruby/hpricot 示例,但使用 Python。
我想用一个空格替换 XML 标记。
使用标准库xml.etree
import xml.etree.ElementTree as ET
tree = ET.parse('sample.xml')
print(ET.tostring(tree.getroot(), encoding='utf-8', method='text'))
我真的很喜欢 BeautifulSoup,如果可以避免的话,我宁愿不在 HTML 上使用正则表达式。
改编自:[this StackOverflow Answer],[BeautifulSoup 文档]
from bs4 import BeautifulSoup
soup = BeautifulSoup(txt) # txt is simply the a string with your XML file
pageText = soup.findAll(text=True)
print ' '.join(pageText)
当然,您可以(并且应该)使用 BeautifulSoup 来导航页面以找到您要查找的内容。
一个不需要像 BeautifulSoup 这样的外部库的解决方案,使用内置的 sax 解析框架:
from xml import sax
class MyHandler(sax.handler.ContentHandler):
def parse(self, filename):
self.text = []
sax.parse(filename, self)
return ''.join(self.text)
def characters(self, data):
self.text.append(data)
result = MyHandler().parse("yourfile.xml")
如果您需要文本中的所有空格完整无缺,也可以ignorableWhitespace
在处理程序类中以相同的方式characters
定义方法。
这个问题实际上是 lxml 教程中的一个示例,它建议使用以下 XPath 表达式之一从文档中获取所有文本内容位作为字符串列表:
root.xpath("string()")
root.xpath("//text()")
然后,您将希望将这些文本位连接到一个大字符串中,str.join
可能str.strip
用于消除每个位上的前导和尾随空格并忽略完全由空格组成的位:
>>> from lxml import etree
>>> root = etree.fromstring("""
... <node>
... some text
... <inner_node someattr="someval"> </inner_node>
... <inner_node>
... foo bar
... </inner_node>
... yet more text
... <inner_node />
... even more text
... </node>
... """)
>>> bits_of_text = root.xpath('//text()')
>>> print(bits_of_text) # Note that some bits are whitespace-only
['\n some text\n ', ' ', '\n ', '\n foo bar\n ', '\n yet more text\n ', '\n even more text\n']
>>> joined_text = ' '.join(
... bit.strip() for bit in bits_of_text
... if bit.strip() != ''
... )
>>> print(joined_text)
some text foo bar yet more text even more text
请注意,顺便说一下,如果您不想在文本位之间插入空格,您可以这样做
etree.tostring(root, method='text', encoding='unicode')
如果您正在处理HTML而不是XML,并且正在使用lxml.html
解析您的 HTML,您可以调用.text_content()
根节点的方法来获取它包含的所有文本(尽管同样不会插入空格):
>>> import lxml.html
>>> root = lxml.html.document_fromstring('<p>stuff<p>more <br><b>stuff</b>bla')
>>> root.text_content()
'stuffmore stuffbla'
编辑:这是当我认为一个空格缩进是正常的时发布的答案,正如评论中提到的那样,这不是一个好的答案。查看其他一些更好的解决方案。这仅出于存档原因留在这里,请勿遵循!
你要求 lxml:
reslist = list(root.iter())
result = ' '.join([element.text for element in reslist])
或者:
result = ''
for element in root.iter():
result += element.text + ' '
result = result[:-1] # Remove trailing space