【问题标题】:Get all text from an XML document?从 XML 文档中获取所有文本?
【发布时间】:2013-07-06 00:16:50
【问题描述】:

如何获取 XML 文档的所有文本内容,作为单个字符串 - like this Ruby/hpricot example,但使用 Python。

我想用一个空格替换 XML 标记。

【问题讨论】:

  • 您接受的答案是错误的,如评论中所述。你会不接受它,以免错误的答案被固定在页面顶部吗?

标签: python xml lxml


【解决方案1】:

使用标准库xml.etree

import xml.etree.ElementTree as ET

tree = ET.parse('sample.xml') 
print(ET.tostring(tree.getroot(), encoding='utf-8', method='text'))

【讨论】:

    【解决方案2】:

    我真的很喜欢 BeautifulSoup,如果可以避免的话,我宁愿不在 HTML 上使用正则表达式。

    改编自:[this StackOverflow Answer][BeautifulSoup documentation]

    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 浏览页面以找到您要查找的内容。

    【讨论】:

      【解决方案3】:

      一个不需要像 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 的方式相同。

      【讨论】:

        【解决方案4】:

        这个问题实际上是an example in the lxml tutorial,它建议使用以下 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'
        

        【讨论】:

          【解决方案5】:

          编辑:这是一个在我认为一个空格缩进是正常的时候发布的答案,正如 cmets 提到的那样,这不是一个 的答案。查看其他一些更好的解决方案。仅出于存档原因将其留在这里,请勿不要关注它!

          你要求 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
          

          【讨论】:

          • 这个答案是错误的。它仅在节点不混合子节点和文本内容时才有效。即 &lt;node&gt;text &lt;subnode&gt;x&lt;/subnode&gt;text2&lt;/node&gt; 失败
          • 是的,这里有一个例子说明如果你只考虑text而忽略tail会发生什么:stackoverflow.com/q/12412264/407651
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多