在验证多个 xml 缓冲区或文件时,是否可以在 libxml2 中重用架构上下文?

Is it possible to reuse schema context in libxml2 when validating multiple xml buffers or files?

提问人:modelmanjohn 提问时间:5/2/2023 最后编辑:modelmanjohn 更新时间:5/2/2023 访问量:22

问:

学习使用 libxml2 库,我正在尝试开发使用相同架构文件来验证 xml 数据的多个缓冲区或 xml 数据的多个文件的代码。但看起来我必须获取一个新的架构解析上下文,将架构文件解析到其中,然后每次都获取一个新的架构上下文,然后才能使用 xml 读取器读取缓冲区或文件。如果我不这样做,它就会出现段错误。下面是一个示例代码(基于 linux 编译)。ctxt_allocated 是初始化为 FALSE 的全局变量,因此它会执行一次 xmlSchemaNewParserCtxt()、xmlSchemaParse() 和 xmlSchemaNewValidCtxt() 调用一次,以生成一次valid_ctxt(另一个全局变量)并反复使用。此代码失败并出现段错误。 想要这样做的原因:最终,我可以有一堆模式来应用于数据,有很多xml缓冲区或xml文件要验证,并且我希望尽可能高效地做到这一点(即,如果可能的话,只做一次,做一次),而不是一遍又一遍地创建/破坏模式上下文。我尝试保存解析器 ctxt、解析的架构和架构 ctxt(以及所有可能的组合)但没有成功,而且文档很少 - 我找不到类似“重新初始化上下文”的东西。

    // This first section is what I'd like to only do ONCE to get valid_cxt
    // but it fails no matter which part I save: the parser context, the parsed schema
    // or the schema context
    if (!ctxt_allocated) {
        if (schema_parser_ctxt = xmlSchemaNewParserCtxt(schemaFilePath)))
        {
            schema = xmlSchemaParse(schema_parser_ctxt);
            xmlSchemaFreeParserCtxt(schema_parser_ctxt);
            if (schema) {
                valid_ctxt = xmlSchemaNewValidCtxt(schema);
                ctx_allocated = true;
            }
        }
    }
    xmlTextReaderPtr reader = NULL;
    reader = xmlReaderForMemory(xmlBuf, strlen(xmlBuf), NULL, NULL, XML_PARSE_HUGE | XML_PARSE_NONET);

    if (reader != NULL) {
        if (valid_ctxt) {
            xmlTextReaderSchemaValidateCtxt(reader, valid_ctxt, 0);
            xmlSchemaSetValidStructuredErrors(valid_ctxt, schemaParseErrorHandler, &has_schema_errors);
        }

        ret = xmlTextReaderRead(reader);
        while (ret == 1 && !has_schema_errors) {
            ret = xmlTextReaderRead(reader);
        }

        if (ret != 0) {
            xmlErrorPtr err = xmlGetLastError();
           printf("Failed to parse. Error %d: %s\n", err->code, err->message);
        }
    }
    else {
        xmlErrorPtr err = xmlGetLastError();
        printf("Failed to get reader!. Error %d: %s\n", err->code, err->message);
    }

尝试了上面的代码。期望有一种方法可以一遍又一遍地重用创建的架构上下文。

XML 架构 libxml2

评论

0赞 nwellnhof 5/6/2023
您可以尝试使用另一个 API 来解析/验证文档,而不是使用另一个 API 来解析/验证文档,无论如何都是相当低效的。我建议和.如果这不起作用,只需每次重新创建验证上下文即可。它不是很贵。xmlTextReaderxmlReadMemoryxmlSchemaValidateDoc

答: 暂无答案