You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XercesC中使用SAX解析器获取DTD内部子集?

用XercesC 3.2.4的SAX解析器提取XML内部DTD子集

在XercesC的SAX2框架中,你可以通过扩展DefaultHandler类并重写特定回调方法来捕获内部DTD子集,核心是利用internalSubset方法——该方法会在解析器遇到内部DTD子集时触发。

实现步骤

  • 自定义一个继承自xercesc::DefaultHandler的处理类,重写internalSubset方法来保存内部子集内容。
  • 可选重写startDTD和endDTD方法,用于标记DTD解析的起止,辅助确认内部子集的上下文。

代码示例

#include <xercesc/sax2/DefaultHandler.hpp>
#include <xercesc/sax2/SAX2XMLReader.hpp>
#include <xercesc/sax2/XMLReaderFactory.hpp>
#include <xercesc/util/XMLString.hpp>
#include <iostream>
#include <string>

XERCES_CPP_NAMESPACE_USE

class DTDHandler : public DefaultHandler {
private:
    std::string internalSubsetContent;
public:
    // 捕获内部DTD子集内容
    void internalSubset(const XMLCh* name, const XMLCh* publicId, const XMLCh* systemId, const XMLCh* internalSubset) override {
        if (internalSubset != nullptr) {
            char* subsetStr = XMLString::transcode(internalSubset);
            internalSubsetContent = subsetStr;
            XMLString::release(&subsetStr);
        }
    }

    // 可选:标记DTD解析开始
    void startDTD(const XMLCh* name, const XMLCh* publicId, const XMLCh* systemId) override {
        char* dtdName = XMLString::transcode(name);
        std::cout << "开始解析DTD: " << dtdName << std::endl;
        XMLString::release(&dtdName);
    }

    // 获取保存的内部子集内容
    const std::string& getInternalSubset() const {
        return internalSubsetContent;
    }

    // 处理解析错误
    void error(const SAXParseException& e) override {
        char* msg = XMLString::transcode(e.getMessage());
        std::cerr << "解析错误: " << msg << " 行号: " << e.getLineNumber() << std::endl;
        XMLString::release(&msg);
    }
};

int main() {
    // 初始化XercesC环境
    try {
        XMLPlatformUtils::Initialize();
    } catch (const XMLException& e) {
        char* msg = XMLString::transcode(e.getMessage());
        std::cerr << "初始化失败: " << msg << std::endl;
        XMLString::release(&msg);
        return 1;
    }

    // 创建SAX解析器实例
    SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
    parser->setFeature(XMLUni::fgSAX2CoreValidation, false);
    parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, false);

    // 绑定自定义处理类
    DTDHandler handler;
    parser->setContentHandler(&handler);
    parser->setDTDHandler(&handler);
    parser->setErrorHandler(&handler);

    // 解析目标XML文件
    try {
        parser->parse("your_target.xml");
        std::cout << "内部DTD子集内容:\n" << handler.getInternalSubset() << std::endl;
    } catch (const XMLException& e) {
        char* msg = XMLString::transcode(e.getMessage());
        std::cerr << "解析异常: " << msg << std::endl;
        XMLString::release(&msg);
    } catch (const SAXParseException& e) {
        char* msg = XMLString::transcode(e.getMessage());
        std::cerr << "解析错误: " << msg << " 行号: " << e.getLineNumber() << std::endl;
        XMLString::release(&msg);
    } catch (...) {
        std::cerr << "未知解析错误" << std::endl;
    }

    // 清理资源
    delete parser;
    XMLPlatformUtils::Terminate();

    return 0;
}

关键说明

  • internalSubset方法的最后一个参数internalSubset就是内部DTD子集的XMLCh编码字符串,需用XMLString::transcode转换为本地编码(如UTF-8)后保存。
  • 默认情况下XercesC的SAX解析器会处理DTD,若之前关闭了DTD相关特性,需重新开启以确保回调触发。
  • 代码包含基础错误处理逻辑,可根据实际需求调整。

内容的提问来源于stack exchange,提问作者user23321476

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:42:21