src/model.c: making node research use hashtable
This commit is contained in:
parent
b2cd2c2fca
commit
1ea9a356a9
71
src/model.c
71
src/model.c
|
@ -40,6 +40,42 @@ struct model_t *knownModels = NULL;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively populates a hash table with XML nodes, using the node paths as keys.
|
||||||
|
*
|
||||||
|
* @param node The current node being processed.
|
||||||
|
* @param hashTable The hash table to populate.
|
||||||
|
* @param currentPath The path to the current node.
|
||||||
|
*/
|
||||||
|
void model_populate_hashtable(xmlNode *node,
|
||||||
|
xmlHashTablePtr hashTable,
|
||||||
|
char *currentPath) {
|
||||||
|
if (node == NULL) return;
|
||||||
|
|
||||||
|
// Skip text nodes and others that are not element nodes
|
||||||
|
if (node->type != XML_ELEMENT_NODE) {
|
||||||
|
model_populate_hashtable(node->next, hashTable, currentPath);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate new path
|
||||||
|
char newPath[1024]; // large enough
|
||||||
|
if (currentPath && strlen(currentPath) > 0) {
|
||||||
|
snprintf(newPath, sizeof(newPath), "%s/%s", currentPath, node->name);
|
||||||
|
} else {
|
||||||
|
snprintf(newPath, sizeof(newPath), "%s", node->name); // Root element
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add current node to hash table with its path as the key
|
||||||
|
xmlHashAddEntry(hashTable, (const xmlChar *)newPath, node);
|
||||||
|
|
||||||
|
// Recurse into child nodes with the updated path
|
||||||
|
model_populate_hashtable(node->children, hashTable, newPath);
|
||||||
|
|
||||||
|
// Continue with the next sibling
|
||||||
|
model_populate_hashtable(node->next, hashTable, currentPath);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finds a node by a path of tags.
|
* Finds a node by a path of tags.
|
||||||
*
|
*
|
||||||
|
@ -48,40 +84,7 @@ struct model_t *knownModels = NULL;
|
||||||
* @return The content of the tag at the end of the path, or NULL if not found.
|
* @return The content of the tag at the end of the path, or NULL if not found.
|
||||||
*/
|
*/
|
||||||
char* model_find_node_by_path(xmlNode *node, const char *path) {
|
char* model_find_node_by_path(xmlNode *node, const char *path) {
|
||||||
char *pathCopy = strdup(path); // Duplicate path to modify it
|
return (xmlNodePtr)xmlHashLookup(hashTable, (const xmlChar *)path);
|
||||||
char *tag = strtok(pathCopy, "/"); // Get the first tag in the path
|
|
||||||
xmlNode *currentNode = node;
|
|
||||||
|
|
||||||
while (tag != NULL && currentNode != NULL) {
|
|
||||||
xmlNode *foundNode = NULL;
|
|
||||||
|
|
||||||
// Search for the tag at the current level
|
|
||||||
for (xmlNode *child = currentNode->children; child; child = child->next) {
|
|
||||||
if (child->type == XML_ELEMENT_NODE && strcmp((const char *)child->name, tag) == 0) {
|
|
||||||
foundNode = child; // Tag found at the current level
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tag = strtok(NULL, "/"); // Move to the next tag in the path
|
|
||||||
|
|
||||||
// If there are more tags to find, continue with the found node's children
|
|
||||||
if (tag != NULL && foundNode != NULL) {
|
|
||||||
currentNode = foundNode;
|
|
||||||
} else {
|
|
||||||
// If this was the last tag, try to get its content
|
|
||||||
if (foundNode != NULL && tag == NULL) {
|
|
||||||
char *content = (char *)xmlNodeGetContent(foundNode);
|
|
||||||
free(pathCopy);
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentNode = NULL; // End loop if tag not found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(pathCopy);
|
|
||||||
return NULL; // Path not fully matched
|
|
||||||
}
|
}
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue