如何让 Python bs4 在 XML 上正常工作?

How to get Python bs4 to work properly on XML?

我正在尝试使用 Python 和 BeautifulSoup 4 (bs4) 将 Inkscape SVG 转换为某些专有软件的 XML 格式。我似乎无法让 bs4 正确解析一个最小的例子。我需要解析器尊重自闭合标签,处理 unicode,而不是添加 html 东西。我认为用 selfClosingTags 指定 'lxml' 解析器应该可以做到,但是不行!检查一下。

#!/usr/bin/python
from __future__ import print_function
from bs4 import BeautifulSoup

print('\nbs4 mangled XML:')
print(BeautifulSoup('<x><c name="b1"><d value="a"/></c></x>',
    features = "lxml", 
    selfClosingTags = ('d')).prettify())

print('''\nExpected output:
<x>
 <c name="b1">
  <d value="a"/>
 </c>
</x>''')

这会打印

bs4 mangled XML:
/usr/local/lib/python2.7/dist-packages/beautifulsoup4-4.4.1-py2.7.egg/bs4/__init__.py:112: UserWarning: BS4 does not respect the selfClosingTags argument to the BeautifulSoup constructor. The tree builder is responsible for understanding self-closing tags.
<html>
 <body>
  <x>
   <c name="b1">
    <d value="a">
    </d>
   </c>
  </x>
 </body>
</html>

Expected output:
<x>
 <c name="b1">
  <d value="a"/>
 </c>
</x>

我查看了相关的 Whosebug 问题,但没有找到解决方案。

This question 解决了 html 样板文件,但仅用于解析 html 的子部分,而不用于解析 xml.

This question 与让 beautifulsoup 4 尊重自动关闭标签有关,没有公认的答案。

This question 似乎表明传递 selfClosingTags 参数应该有所帮助,但如您所见,这现在会生成警告 BS4 does not respect the selfClosingTags argument,并且自关闭标签被破坏。

This question建议使用"xml"(不是"lxml")会导致空标签自动自闭。这 可能 适合我的目的,但是将 "xml" 解析器应用于我的实际数据失败,因为文件包含 unicode,"xml" 解析器不支持。

"xml"和"lxml"有区别吗,标准中"xml"不能支持unicode,"lxml" 不能包含自闭标签?也许我只是想做一些被禁止的事情?

如果您希望结果输出为 xml,则将其解析为那样。您的 xml 数据可以包含 unicode,但是,您需要声明编码:

#!/usr/bin/env python
# -*- encoding: utf8 -*-

The SelfClosingTags is no longer recognized. Instead, Beautiful Soup considers any empty tag to be an empty-element tag. If you add a child to an empty-element tag, it stops being an empty-element tag.

将你的函数改成这样应该可行(除了编码之外):

print(BeautifulSoup('<x><c name="b1"><d value="a®"/></c></x>',
    features = "xml").prettify())

结果:

<?xml version="1.0" encoding="utf-8"?>
<x>
 <c name="b1">
  <d value="aÂŽ"/>
 </c>
</x>