我正在使用libxml2在c中创建和读取包含我正在编写的程序的配置信息的XML文件。程序生成自己的配置文件(或其他程序向其发送配置文件,并要求程序根据配置文件运行),因此XML配置文件不需要非常容易被人阅读。
这些配置文件包含很多值,而且非常长。所以现在我有一个创建XML文件的函数和另一个读取XML文件的函数。但是,无论何时我更改写入XML函数都需要更改read xml函数。 所以没有实际的代码重复,但有些东西真的很接近(即.BAD),因为配置文件太长,所以要确保一切都在读取和写入相同的东西是相当繁琐的
这是目前的设置。
struct config_data
{
// category one
int X
int Y
// category two
int Z
int A
}
int makeXMLsheet(char* fileout)
{
xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL; /* node pointers */
LIBXML_TEST_VERSION;
doc = xmlNewDoc((xmlChar*) "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "configuration_file");
xmlDocSetRootElement(doc, root_node);
// catogory one
xmlNodePtr category_one = xmlNewChild(root_node, NULL, BAD_CAST "category_one", NULL);
xmlNewChild(category_one, NULL, BAD_CAST "x", BAD_CAST "12345");
xmlNewChild(category_one, NULL, BAD_CAST "y", BAD_CAST "1");
// catogory two
xmlNodePtr category_two = xmlNewChild(root_node, NULL, BAD_CAST "category_two", NULL);
xmlNewChild(category_two, NULL, BAD_CAST "Z", BAD_CAST "12345");
xmlNewChild(category_two, NULL, BAD_CAST "A", BAD_CAST "1");
xmlSaveFormatFileEnc(fileout, doc, "UTF-8", 1);
xmlFreeDoc(doc);
xmlCleanupParser();
return 0;
}
int readXMLsheet(char* filename,struct *config_data)
{
xmlDocPtr doc = getdoc(filename);
config_data->X = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_one/X");
config_data->Y = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_one/Y");
config_data->Z = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_two/Z");
config_data->A = getIntegerFromXML(0,doc,(xmlChar*)"//configuration_file/category_two/a");
xmlFreeDoc(doc);
return 0;
}
哪里
int getIntegerFromXML(int defaultValue, xmlDocPtr doc, xmlChar *xpath)
正如其名称所示,并从打开的XML文档中获取具有xpath位置的整数,如果失败,则使用默认值填充它,以便程序不会崩溃和刻录。
所以我想尝试一下如何将读写函数合并为一个。我的示例struct config-data与我在配置结构中实际拥有的值的数量相比很小,所以将它们结合起来可以更容易地跟踪所有事情。
所以我在想这样的事情。
int openXMLvalue(X, Y, Z, readOrWrite, defaultValue, value);
其中X, Y, Z
是父节点,但可能多于或少于3.
关于如何做到这一点的任何想法?也许做一些类型的数组?
答案 0 :(得分:0)
我会创建填充(或序列化)通用配置结构的通用读写函数。
简化的情况是使用get / set方法在内存中创建键/值结构。通用writeToXml函数只是创建包含值的键名称的元素。
如果有必要,可以使用分层树结构,并且可能在读取配置文件时添加一些验证规则(一个简单的方法是使用XML Schema进行验证)来验证所需的配置值是否存在并且是有效的。
添加,更改或删除配置值只需要执行以下步骤(请注意,读取或写入功能都不需要更新):
答案 1 :(得分:0)
由于配置文件大小较大,我们切换到使用sqlite。然后我们创建了一个读取数据库并生成xml表的函数,我们创建了一个函数,它将读取xml表并填充数据库,并处理函数以打印数据库以粗体并填充C结构。认为这会让生活变得更轻松。