我需要转义一个无效的 XML 文件中的特殊字符,该文件大约有 5000 行。这里是我要处理的 XML 示例:
<root>
<element>
<name>name & surname</name>
<mail>name@name.org</mail>
</element>
</root>
问题出在名称中的特殊字符"&"。您如何使用Python库转义此类特殊字符?我没有找到一种使用BeautifulSoup进行转义的方法。
我需要转义一个无效的 XML 文件中的特殊字符,该文件大约有 5000 行。这里是我要处理的 XML 示例:
<root>
<element>
<name>name & surname</name>
<mail>name@name.org</mail>
</element>
</root>
问题出在名称中的特殊字符"&"。您如何使用Python库转义此类特殊字符?我没有找到一种使用BeautifulSoup进行转义的方法。
如果您不关心XML中的无效字符,可以使用XML解析器的 recover
选项(请参见使用lxml.etree.iterparse解析破碎的XML):
from lxml import etree
parser = etree.XMLParser(recover=True) # recover from bad characters.
root = etree.fromstring(broken_xml, parser=parser)
print etree.tostring(root)
<root>
<element>
<name>name surname</name>
<mail>name@name.org</mail>
</element>
</root>
你可能只是想在将HTML传递给BeautifulSoup之前对其进行一些简单的正则表达式操作。
更简单的方法是,如果代码中没有任何SGML实体(&...;
),html=html.replace('&','&')
就可以解决问题。
否则,请尝试以下方法:
x ="<html><h1>Fish & Chips & Gravy</h1><p>Fish & Chips & Gravy</p>"
import re
q=re.sub(r'&([^a-zA-Z#])',r'&\1',x)
print q
本质上,正则表达式查找不跟随字母数字或#字符的&
。它不会处理行末的和号,但这可能是可以修复的。
这个答案提供了XML清理函数,虽然它们不会转义未转义的字符,而是直接删除它们。
问题想知道如何使用Beautiful Soup。 这里有一个函数,它将使用Beautiful Soup对小型XML bytes
对象进行清理。它已经在beautifulsoup4==4.8.0
和lxml==4.4.0
的包要求下进行了测试。请注意,bs4
需要lxml
。
import xml.etree.ElementTree
import bs4
def sanitize_xml(content: bytes) -> bytes:
# Ref: https://dev59.com/U1TTa4cB1Zd3GeqPqj-S#57450722/
try:
xml.etree.ElementTree.fromstring(content)
except xml.etree.ElementTree.ParseError:
return bs4.BeautifulSoup(content, features='lxml-xml').encode()
return content # already valid XML
显然,当可以仅使用lxml
时,同时使用bs4
和lxml
没有太大意义。这个lxml==4.4.0
使用的清理函数本质上是从jfs的答案中派生出来的。
import lxml.etree
def sanitize_xml(content: bytes) -> bytes:
# Ref: https://dev59.com/U1TTa4cB1Zd3GeqPqj-S#57450722/
try:
lxml.etree.fromstring(content)
except lxml.etree.XMLSyntaxError:
root = lxml.etree.fromstring(content, parser=lxml.etree.XMLParser(recover=True))
return lxml.etree.tostring(root)
return content # already valid XML
<name>name & surname</name>
不是格式良好的XML。应该是:
<name>name & surname</name>
所有符合标准的 XML 工具都应该创建这个 - 通常你不必担心。如果你创建了一个带有 '&' 字符的字符串,那么 XML 工具将输出转义版本。如果你手动创建字符串,则需要确保它已经被转义。如果你使用 XML 编辑器,它应该会为你转义。
如果文件是由别人给你的,请将其退回并告诉他们它不是格式良好的。如果他们已经不存在了,你将不得不使用纯文本编辑器。这很脆弱和混乱,但没有其他办法。如果文件中有其他用于转义的 & 符号,则该文件是垃圾。