我有一个使用 ET.XMLParser 来解析 CppCheck XML 报告文件的 Python 模块。当尝试解析字符串中包含“<”的 XML 元素中的属性之一时,它会令人窒息,它会将其解释为格式错误的 XML,例如:
<error msg="Include file <iostream> not found.">
(注意字符和“iostream”之间的空格必须放置,否则它不会在这个论坛中正确发布)
当我这样做时,它很令人窒息:
ET.parse(xml_filename)
显然我无法转义文件中的所有“<”和“>”。有什么建议么?
遇到的问题是 CppCheck 生成的 XML 报告没有正确转义
<iostream>
中的
<
字符。解决此问题的最佳方法是在源头修复 CppCheck 报告,确保它生成格式良好的 XML。
但是,如果无法修改 CppCheck 的输出,则可以使用以下几种方法在 Python 中解决此问题:
1. 使用正则表达式预处理 XML:
在解析 XML 之前,可以使用正则表达式替换
<
字符(不在标签内)。
import re
import xml.etree.ElementTree as ET
def fix_xml(xml_string):
"""修复 XML 字符串中的无效 '<' 字符。"""
return re.sub(r'&(?!(lt;|gt;|amp;|apos;|quot;))', '&', xml_string)
# 读取 XML 文件
with open(xml_filename, 'r') as f:
xml_string = f.read()
# 使用正则表达式修复 XML
fixed_xml_string = fix_xml(xml_string)
# 解析修复后的 XML
root = ET.fromstring(fixed_xml_string)
# 现在可以正常解析 XML 了
# ...
这个方法利用了“negative lookahead assertion” (
(?!...)
) 来确保只替换不在已知实体 (
<
,
>
,
&
,
'
,
"
) 中的
&
字符。
2. 使用 SAX 解析器:
SAX(Simple API for XML)解析器逐行读取 XML,并为遇到的每个元素触发事件。可以使用 SAX 解析器拦截字符数据事件,并在解析 XML 之前手动替换无效字符。
from xml.sax import make_parser, handler
class ContentHandler(handler.ContentHandler):
def __init__(self):
self.data = ''
def characters(self, content):
self.data += content.replace('<', '<').replace('>', '>')
# 创建 SAX 解析器
parser = make_parser()
# 设置 ContentHandler
handler = ContentHandler()
parser.setContentHandler(handler)
# 解析 XML 文件
with open(xml_filename, 'r') as f:
parser.parse(f)
# 获取解析后的数据
data = handler.data
# 使用 ElementTree 或其他 XML 解析库解析数据
# ...
这种方法需要编写更多代码,但它可以更好地控制 XML 解析过程,并且可能比使用正则表达式更有效。
无论选择哪种方法,修复 CppCheck 报告以生成格式良好的 XML 都是最佳的长期解决方案。
标签:python,xml,xml-parsing From: 78790276