首页 > 解决方案 > Beautifulsoup - 如何独立处理 xml 中的每一段文本?replace_with 销毁孩子

问题描述

我想对每段文本进行一次字符串替换,并保持树结构。

例如,每个字符串将被反转:abc > cba。

如果我将“replace_with()”应用于/a 父节点,它只会加入嵌套文本,并展平父元素。

nodes = soup.find_all(['a','b'])
for node in nodes:
    rep = node.text[::-1]
    node.string.replace_with(rep)

输入:

<xml>
<a>abc
    <b>def </b>
    ghi
        <a>jkl 
            <b>mno</b>
        jkl </a>
    ghi
    <b>def </b>
abc</a>
</xml>

输出:

<xml> cba fed ihg    lkj ihg fed cbA </xml>

此外,在某些情况下(此处未显示),循环处理了内部子级,并在父级处再次对其进行了重新处理,导致结果好坏参半;例如

abc def abc > cba def cba

我想找到一种方法来检索每段文本,并独立处理它。

如何?

标签: pythonxmlbeautifulsoup

解决方案


您可以使用.find_all(text=True)仅查找文本节点,然后处理它们。

例如:

txt = '''<xml>
<a>abc
    <b>def </b>
    ghi
        <a>jkl
            <b>mno</b>
        jkl </a>
    ghi
    <b>def </b>
abc</a>
</xml>'''

soup = BeautifulSoup(txt, 'html.parser')

for t in soup.find_all(text=True):
    t.replace_with(t[::-1])

print(soup.prettify())

印刷:

<xml>
 <a>
  cba
  <b>
   fed
  </b>
  ihg
  <a>
   lkj
   <b>
    onm
   </b>
   lkj
  </a>
  ihg
  <b>
   fed
  </b>
  cba
 </a>
</xml>

推荐阅读