这段代码是做什么用的int edit_replace_intrenal(xmlDocPtr orig_doc, xmlNodePtr edit_node, xmlDocPtr model, keyList keys) { xmlNodePtr old; int r; char msg = NULL; if ((orig_doc == NULL) || (edit_node ==NULL)) { return (EXIT_FAILURE); } DBG("\n%s/%d edit_node=%s parent %s parent child %s========================", func,LINE,edit_node->name,edit_node->parent->name,edit_node->parent->children->name); old = find_element_equiv(orig_doc, edit_node, model, keys); //USER("%s/%d old node=%s======================\n",func,LINE,old?old->name:"is not found"); if (old) { //USER("%s/%d old is exist node=%s======================\n",func,LINE,old->name); / remove operation attribute / xmlRemoveProp(xmlHasNsProp(edit_node, BAD_CAST NC_EDIT_ATTR_OP, BAD_CAST NC_NS_BASE)); //nc_clear_namespaces(edit_node); / * replace old configuration data with the new data * Do this removing the old node and creating a new one to cover actual * "moving" of the instance of the list/leaf-list using YANG's insert * attribute */ xmlUnlinkNode(old); xmlFreeNode(old); } return edit_create_internal(orig_doc, edit_node, model, keys); }
时间: 2023-09-06 11:10:01 浏览: 76
这段代码是一个函数,名为`edit_replace_internal`。它负责替换XML文档中的一个节点。具体来说,它接收四个参数:`orig_doc`表示原始XML文档,`edit_node`表示要替换的节点,`model`表示用于替换的模板文档,`keys`表示关键字列表。函数首先会检查`orig_doc`和`edit_node`是否为空,如果是就返回`EXIT_FAILURE`。然后它会调用`find_element_equiv`函数在`orig_doc`中查找等效的节点。如果找到了等效节点,函数会删除旧节点并创建一个新节点,最后调用`edit_create_internal`函数创建新节点。
相关问题
一句句解释分析细致讲解一下这段代码int edit_replace_intrenal(xmlDocPtr orig_doc, xmlNodePtr edit_node, xmlDocPtr model, keyList keys) { xmlNodePtr old; int r; char *msg = NULL; if ((orig_doc == NULL) || (edit_node ==NULL)) { return (EXIT_FAILURE); } DBG("\n%s/%d edit_node=%s parent %s parent child %s========================", __func__,__LINE__,edit_node->name,edit_node->parent->name,edit_node->parent->children->name); old = find_element_equiv(orig_doc, edit_node, model, keys); if (old) { xmlRemoveProp(xmlHasNsProp(edit_node, BAD_CAST NC_EDIT_ATTR_OP, BAD_CAST NC_NS_BASE)); xmlUnlinkNode(old); xmlFreeNode(old); } return edit_create_internal(orig_doc, edit_node, model, keys); }
这段代码是一个函数定义,函数名为 `edit_replace_internal`,接受四个参数:`orig_doc`(原始文档的指针)、`edit_node`(待编辑节点的指针)、`model`(模型文档的指针)和 `keys`(键列表)。
函数的目的是执行替换操作,将 `edit_node` 在原始文档 `orig_doc` 中找到的等价节点 `old` 进行替换。
首先,定义了一个整数变量 `r` 和一个字符指针变量 `msg`,并初始化为 NULL。
然后,进行参数的有效性检查,如果 `orig_doc` 或 `edit_node` 为空指针,则返回 `EXIT_FAILURE` 表示失败。
接下来,打印调试信息,输出函数名、行号以及相关节点的名称信息。
然后,调用 `find_element_equiv` 函数,在原始文档 `orig_doc` 中找到与 `edit_node` 等价的节点 `old`。
如果找到了等价节点 `old`,则首先移除 `edit_node` 上的属性 `NC_EDIT_ATTR_OP`,然后将等价节点 `old` 从文档中解链和释放内存。
最后,调用 `edit_create_internal` 函数,执行创建操作,将 `edit_node` 插入到原始文档 `orig_doc` 中,并返回相应的结果。
总体来说,这段代码是一个用于执行替换操作的函数。它首先进行参数有效性检查,然后根据参数在原始文档中找到等价节点,并进行替换操作。最后,调用另一个函数执行创建操作,将编辑节点插入原始文档中。
解释分析细致讲解一下这段代码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 表示执行失败。
阅读全文