XercesDOMParser解析含&的属性值失败,如何兼顾XML合法性与链接有效性?
解决Xerces C++ 3.2.2解析含未转义&的HTML标签失败问题
问题根源
你开启了XercesDOMParser的始终验证模式,而XML规范严格要求所有&必须转义为&(除非是合法实体引用)。但HTML允许未转义的&(只要后续不是标准实体格式),这种XML与HTML的语法差异导致解析失败,根元素返回null。
解决方案
方案1:关闭严格验证,调整解析器特性
直接修改现有XercesDOMParser的配置,关闭验证并允许未识别的实体,这样解析器会忽略未转义&的语法错误,正常解析并保留原始链接:
// 初始化解析器 XercesDOMParser* parser = new XercesDOMParser(); // 关闭验证模式(关键) parser->setValidationScheme(XercesDOMParser::Val_Never); // 禁用命名空间、Schema(保持你的原有配置) parser->setDoNamespaces(false); parser->setDoSchema(false); parser->setLoadExternalDTD(false); // 允许未识别的实体,避免&引发错误 parser->setFeature(XMLUni::fgXercesAllowUnrecognizedEntities, true); parser->setFeature(XMLUni::fgXercesSkipUnknownEntities, true);
优缺点:修改成本极低,无需更换组件;但关闭验证后会失去XML语法检查能力,若需确保HTML结构正确性,需额外处理。
方案2:改用Xerces HTML解析器
Xerces C++提供了专门的HTML解析组件(需确保编译时启用HTML模块),它遵循HTML解析规则,原生支持未转义的&,更适合处理HTML内容:
// 使用HTMLDOMBuilder代替XercesDOMParser HTMLDOMBuilder* htmlParser = new HTMLDOMBuilder(); // 禁用命名空间(匹配你的原有需求) htmlParser->setFeature(XMLUni::fgDOMNamespaces, false); // 禁用外部DTD加载(保持原有配置) htmlParser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); // 解析HTML内容(示例:解析缓冲区) htmlParser->parseBuffer(htmlContent, htmlContentLength); DOMDocument* doc = htmlParser->getDocument();
优缺点:完全适配HTML语法,能处理各种HTML不规范写法;但需确认Xerces编译时包含HTML模块,可能需要调整项目编译配置。
方案3:临时转义+解析后恢复(不推荐)
若必须保留验证模式,可在解析前将href中的&临时替换为自定义实体(如&temp_amp;),解析完成后再替换回&。但这种方法实现繁琐,容易遗漏边缘情况(如已转义的&被误处理),仅作为极端场景的备选。
注意事项
- 若你的工具类主要处理HTML内容,优先选择方案2,更贴合HTML的实际使用场景。
- 方案1中关闭验证后,需自行处理HTML结构的合法性问题(如未闭合标签)。
内容的提问来源于stack exchange,提问作者Bharath Gade
相关产品推荐
相关产品推荐

