分析下面代码:int edit_config_internal(xmlDocPtr repo, xmlDocPtr edit, struct ncds_ds* ds, NC_EDIT_DEFOP_TYPE defop) { xmlXPathObjectPtr nodes; int i; char *msg = NULL; xmlNodePtr orig_node, edit_node, parent_node,model_node = NULL; keyList keys; xmlDocPtr model = ds->ext_model; DBG("%s BEGIN\n", __FILE__); keys = get_keynode_list(model); nodes = get_operation_elements(NC_EDIT_OP_REPLACE, edit); if (nodes != NULL) { if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) { DBG("%s/%d something to replace nodeNr %d",__func__,__LINE__,nodes->nodesetval->nodeNr); /* something to replace */ for (i = 0; i < nodes->nodesetval->nodeNr; i++) { if (edit_replace_intrenal(repo, nodes->nodesetval->nodeTab[i], model, keys) != EXIT_SUCCESS) { xmlXPathFreeObject(nodes); /*add by yxc for 2-merge begin*/ goto error; /*add by yxc for 2-merge end*/ } } } else { DBG("Replace xmlXPathNodeSetIsEmpty\n"); } xmlXPathFreeObject(nodes); } if (defop == NC_EDIT_DEFOP_MERGE) { /* replace whole document */ if (edit->children != NULL) { if (edit_merge_intrenal(repo, edit->children, model, keys) != EXIT_SUCCESS) { goto error; } } } keyListFree(keys); return EXIT_SUCCESS; error: if (keys != NULL ) { keyListFree(keys); } return EXIT_FAILURE; }
时间: 2024-02-14 18:36:14 浏览: 56
这段代码是一个函数,名为edit_config_internal。函数接受4个参数:一个指向目标XML文档的指针repo,一个指向编辑XML文档的指针edit,一个指向数据结构的指针ds,和一个编辑操作的类型defop。
函数的主要功能是对目标XML文档进行编辑操作。首先,它调用get_keynode_list函数获取XML文档中的关键节点列表,并通过get_operation_elements函数获取需要替换的XML节点。然后,在for循环中遍历这些节点,调用edit_replace_internal函数对节点进行替换操作。如果替换操作失败,则通过goto语句跳转到error标记处进行错误处理。接着,如果编辑操作的类型是NC_EDIT_DEFOP_MERGE,则将整个编辑文档合并到目标文档中。最后,释放关键节点列表的内存空间。
如果函数执行过程中发生错误,则通过goto语句跳转到error标记处进行错误处理,并释放关键节点列表的内存空间。函数返回值为EXIT_SUCCESS或EXIT_FAILURE,表示函数执行成功或失败。
相关问题
int edit_config_internal(xmlDocPtr repo, xmlDocPtr edit, struct ncds_ds* ds, NC_EDIT_DEFOP_TYPE defop) { xmlXPathObjectPtr nodes; int i; char *msg = NULL; xmlNodePtr orig_node, edit_node, parent_node,model_node = NULL; keyList keys; xmlDocPtr model = ds->ext_model; DBG("%s BEGIN\n", __FILE__); keys = get_keynode_list(model); /* delete operations */ nodes = get_operation_elements(NC_EDIT_OP_DELETE, edit); if (nodes != NULL) { if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) { VERB("DELETE !xmlXPathNodeSetIsEmpty\n "); /* something to delete */ for (i = 0; i < nodes->nodesetval->nodeNr; i++) { edit_node = nodes->nodesetval->nodeTab[i]; model_node = find_element_model(edit_node, model); if (is_mandatory(model_node)) { ERROR("NC_ERR_DEL_MANDATORY_NOT_SUPPORT(%s:%d)\n",__FILE__, __LINE__); } orig_node = find_element_equiv(repo, edit_node, model, keys); for (; orig_node != NULL; orig_node = find_element_equiv(repo, edit_node, model, keys)) { parent_node = orig_node->parent; xmlUnlinkNode(orig_node); orig_node->parent = parent_node; edit_delete(orig_node); } /* remove the node from the edit document */ edit_delete(edit_node); } } else { DBG("Delete xmlXPathNodeSetIsEmpty\n"); } xmlXPathFreeObject(nodes); }
这是一个函数的具体实现,它是根据函数声明中的参数来实现编辑配置的功能。
该函数的主要功能是处理删除操作,它首先从编辑文档中获取要删除的操作节点,然后遍历每个操作节点,将其对应的节点从配置仓库中删除。具体实现过程如下:
1. 获取所有操作类型为 NC_EDIT_OP_DELETE 的节点;
2. 如果获取的节点集合不为空,则遍历每个操作节点;
3. 找到该操作节点在数据模型中的对应节点;
4. 判断该节点是否是必需的;
5. 根据该节点在配置仓库中的路径找到对应的节点;
6. 将该节点从配置仓库中删除;
7. 将该节点从编辑文档中删除。
需要注意的是,该函数还调用了一些其他的函数来实现具体的功能,例如 get_operation_elements()、find_element_model() 等。
解释分析细致讲解一下这段代码int edit_config_internal(xmlDocPtr repo, xmlDocPtr edit, struct ncds_ds* ds, NC_EDIT_DEFOP_TYPE defop) { xmlXPathObjectPtr nodes; int i; char *msg = NULL; xmlNodePtr orig_node, edit_node, parent_node,model_node = NULL; keyList keys; xmlDocPtr model = ds->ext_model; DBG("%s BEGIN\n", __FILE__); keys = get_keynode_list(model); nodes = get_operation_elements(NC_EDIT_OP_REMOVE, edit); if (nodes != NULL) { if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) { VERB("DELETE !xmlXPathNodeSetIsEmpty\n "); for (i = 0; i < nodes->nodesetval->nodeNr; i++) { edit_node = nodes->nodesetval->nodeTab[i]; model_node = find_element_model(edit_node, model); if (is_mandatory(model_node)) { ERROR("NC_ERR_DEL_MANDATORY_NOT_SUPPORT(%s:%d)\n",__FILE__, __LINE__); } orig_node = find_element_equiv(repo, edit_node, model, keys); for (; orig_node != NULL; orig_node = find_element_equiv(repo, edit_node, model, keys)) { parent_node = orig_node->parent; xmlUnlinkNode(orig_node); orig_node->parent = parent_node; edit_delete(orig_node); } edit_delete(edit_node); } } else { DBG("Delete xmlXPathNodeSetIsEmpty\n"); } xmlXPathFreeObject(nodes); } nodes = get_operation_elements(NC_EDIT_OP_REPLACE, edit); if (nodes != NULL) { if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) { DBG("%s/%d something to replace nodeNr %d",__func__,__LINE__,nodes->nodesetval->nodeNr); for (i = 0; i < nodes->nodesetval->nodeNr; i++) { if (edit_replace_intrenal(repo, nodes->nodesetval->nodeTab[i], model, keys) != EXIT_SUCCESS) { xmlXPathFreeObject(nodes); goto error; } } } else { DBG("Replace xmlXPathNodeSetIsEmpty\n"); } xmlXPathFreeObject(nodes); } if (defop == NC_EDIT_DEFOP_MERGE) { if (edit->children != NULL) { if (edit_merge_intrenal(repo, edit->children, model, keys) != EXIT_SUCCESS) { goto error; } } } keyListFree(keys); return EXIT_SUCCESS; error: if (keys != NULL ) { keyListFree(keys); } return EXIT_FAILURE; }
这段代码是一个 C 语言函数,主要作用是根据用户提交的 XML 文档,修改另一个 XML 文档中的元素节点。函数接受四个参数:
- xmlDocPtr repo:需要被修改的 XML 文档。
- xmlDocPtr edit:包含修改操作的 XML 文档。
- struct ncds_ds* ds:外部数据模型。
- NC_EDIT_DEFOP_TYPE defop:修改操作类型。
函数的返回值为 int 类型,表示执行结果,EXIT_SUCCESS 表示成功,EXIT_FAILURE 表示失败。
下面是函数的主要实现:
1. 获取关键节点列表
```c
keys = get_keynode_list(model);
```
该语句调用 get_keynode_list 函数获取外部数据模型中的关键节点列表,并将其赋值给变量 keys。
2. 删除操作
```c
nodes = get_operation_elements(NC_EDIT_OP_REMOVE, edit);
if (nodes != NULL) {
if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) {
for (i = 0; i < nodes->nodesetval->nodeNr; i++) {
edit_node = nodes->nodesetval->nodeTab[i];
model_node = find_element_model(edit_node, model);
if (is_mandatory(model_node)) {
ERROR("NC_ERR_DEL_MANDATORY_NOT_SUPPORT(%s:%d)\n",__FILE__, __LINE__);
}
orig_node = find_element_equiv(repo, edit_node, model, keys);
for (; orig_node != NULL; orig_node = find_element_equiv(repo, edit_node, model, keys)) {
parent_node = orig_node->parent;
xmlUnlinkNode(orig_node);
orig_node->parent = parent_node;
edit_delete(orig_node);
}
edit_delete(edit_node);
}
}
xmlXPathFreeObject(nodes);
}
```
该语句首先调用 get_operation_elements 函数获取修改操作中所有的删除操作节点,并将其赋值给变量 nodes。然后,如果 nodes 不为空且 nodes 中的节点数不为零,则遍历 nodes 中的所有节点,依次执行以下操作:
- 从 edit_node 所在的数据模型中找到与之相等的模型节点,并将其赋值给变量 model_node。
- 如果 model_node 是必须存在的节点,则输出错误信息。
- 从 repo 文档中查找与 edit_node 相等的节点,并将其赋值给变量 orig_node。
- 如果 orig_node 不为空,则执行以下操作:
- 获取 orig_node 的父节点,将 orig_node 从原来的树形结构中删除。
- 将 orig_node 的父节点设置为 parent_node。
- 调用 edit_delete 函数删除 orig_node。
3. 替换操作
```c
nodes = get_operation_elements(NC_EDIT_OP_REPLACE, edit);
if (nodes != NULL) {
if (!xmlXPathNodeSetIsEmpty(nodes->nodesetval)) {
for (i = 0; i < nodes->nodesetval->nodeNr; i++) {
if (edit_replace_intrenal(repo, nodes->nodesetval->nodeTab[i], model, keys) != EXIT_SUCCESS) {
xmlXPathFreeObject(nodes);
goto error;
}
}
}
xmlXPathFreeObject(nodes);
}
```
该语句首先调用 get_operation_elements 函数获取修改操作中所有的替换操作节点,并将其赋值给变量 nodes。然后,如果 nodes 不为空且 nodes 中的节点数不为零,则遍历 nodes 中的所有节点,依次调用 edit_replace_intrenal 函数替换 XML 文档中的节点。
4. 合并操作
```c
if (defop == NC_EDIT_DEFOP_MERGE) {
if (edit->children != NULL) {
if (edit_merge_intrenal(repo, edit->children, model, keys) != EXIT_SUCCESS) {
goto error;
}
}
}
```
如果 defop 是 NC_EDIT_DEFOP_MERGE,表示需要执行合并操作。该语句首先判断 edit 文档是否包含子节点,如果包含,则调用 edit_merge_intrenal 函数合并 XML 文档中的节点。
5. 释放关键节点列表
```c
keyListFree(keys);
```
该语句调用 keyListFree 函数释放关键节点列表。
6. 错误处理
```c
error:
if (keys != NULL ) {
keyListFree(keys);
}
return EXIT_FAILURE;
```
如果在执行函数过程中出现错误,则跳转到 error 标签处执行错误处理代码。该代码首先释放关键节点列表,并返回 EXIT_FAILURE 表示执行失败。
阅读全文