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.
|
||||
*
|
||||
|
@ -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.
|
||||
*/
|
||||
char* model_find_node_by_path(xmlNode *node, const char *path) {
|
||||
char *pathCopy = strdup(path); // Duplicate path to modify it
|
||||
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
|
||||
return (xmlNodePtr)xmlHashLookup(hashTable, (const xmlChar *)path);
|
||||
}
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in New Issue