diff --git a/src/model.c b/src/model.c index 16b0bad..3528ab4 100644 --- a/src/model.c +++ b/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); } /* -------------------------------------------------------------------------- */