Xerces C++ SAX2解析后缺失元素属性复制类的相关问题
Xerces-C++ SAX2解析属性留存问题解答
关于AttributesImpl类的存在性说明
文档与源码注释中提到的AttributesImpl辅助类 确实未在所有正式发布的Xerces-C++版本中实现,覆盖从早期2.x系列到当前最新3.2.3版本的全量发行包,属于典型的文档注释与实际代码交付不一致的历史遗留问题,整个源码树中不存在该类的定义与实现,无需在头文件、库文件中额外查找。
官方可用的属性跨作用域留存方案
Xerces-C++官方没有提供封装好的属性复制工具类,但完全不需要从零解析Attributes内部逻辑,也不需要缓存整个XML文档(不会违背SAX流式解析的设计初衷),直接基于Attributes类对外暴露的稳定公开API,即可用极少量代码实现属性的安全拷贝:
- 核心逻辑仅依赖
Attributes类的公开只读方法,不触碰任何内部未暴露的实现逻辑,全版本兼容:getLength():获取当前元素的属性总数getURI(index):获取指定索引属性的命名空间URIgetLocalName(index):获取指定索引属性的本地名getQName(index):获取指定索引属性的限定名getValue(index):获取指定索引属性的值getType(index):获取指定索引属性的类型
- 参考实现代码如下:
#include <vector> #include <xercesc/sax2/Attributes.hpp> #include <xercesc/util/XMLString.hpp> // 自定义属性存储结构 struct PersistedAttribute { XMLCh* nsUri; XMLCh* localName; XMLCh* qualifiedName; XMLCh* value; XMLCh* type; }; // 自定义SAX2处理器的startElement回调实现 void CustomSaxHandler::startElement( const XMLCh* const nsUri, const XMLCh* const localName, const XMLCh* const qName, const xercesc::Attributes& attrs ) { std::vector<PersistedAttribute> attrStore; const XMLSize_t attrCount = attrs.getLength(); attrStore.reserve(attrCount); for (XMLSize_t idx = 0; idx < attrCount; idx++) { PersistedAttribute attr; // 必须用XMLString::replicate做深拷贝,不可直接存储返回的指针 attr.nsUri = xercesc::XMLString::replicate(attrs.getURI(idx)); attr.localName = xercesc::XMLString::replicate(attrs.getLocalName(idx)); attr.qualifiedName = xercesc::XMLString::replicate(attrs.getQName(idx)); attr.value = xercesc::XMLString::replicate(attrs.getValue(idx)); attr.type = xercesc::XMLString::replicate(attrs.getType(idx)); attrStore.push_back(attr); } // attrStore可安全脱离当前startElement作用域使用,不会被后续解析流程覆盖 // 注意使用完成后手动调用XMLString::release释放所有拷贝的XMLCh字符串,避免内存泄漏 }
注意事项:
Attributes类各get方法返回的XMLCh*指针指向解析器内部的复用缓冲区,一旦退出startElement作用域、解析器开始处理后续节点,缓冲区内容就会被覆写,必须通过XMLString::replicate做深拷贝才能长期留存数据。
方案特性说明
- 内存开销极低:仅拷贝当前正在解析的单个元素的属性数据,内存占用和单节点最大属性数正相关,不会缓存整份XML文档,完全符合SAX流式解析低内存占用的设计目标
- 兼容性强:所有调用的API均为Xerces-C++ SAX2模块对外暴露的稳定接口,从2.x版本到最新3.2.x版本均无接口变动,无需担心版本升级导致兼容问题
- 实现成本极低:仅需在SAX处理器回调中增加几十行拷贝逻辑,不需要修改Xerces库源码,也不需要基于库做二次开发扩展
内容的提问来源于stack exchange,提问作者chars
相关产品推荐
相关产品推荐

