You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.1 KiB
76 lines
2.1 KiB
#include "xmpmeta/xml/search.h"
|
|
|
|
#include <stack>
|
|
#include <string>
|
|
|
|
#include "android-base/logging.h"
|
|
#include "xmpmeta/xml/utils.h"
|
|
|
|
using ::dynamic_depth::xmpmeta::xml::FromXmlChar;
|
|
|
|
namespace dynamic_depth {
|
|
namespace xmpmeta {
|
|
namespace xml {
|
|
|
|
xmlNodePtr DepthFirstSearch(const xmlDocPtr parent, const char* name) {
|
|
return DepthFirstSearch(parent, "", name);
|
|
}
|
|
|
|
xmlNodePtr DepthFirstSearch(const xmlDocPtr parent, const char* prefix,
|
|
const char* name) {
|
|
if (parent == nullptr || parent->children == nullptr) {
|
|
LOG(ERROR) << "XML doc was null or has no XML nodes";
|
|
return nullptr;
|
|
}
|
|
xmlNodePtr result;
|
|
for (xmlNodePtr node = parent->children; node != nullptr; node = node->next) {
|
|
result = DepthFirstSearch(node, prefix, name);
|
|
if (result != nullptr) {
|
|
return result;
|
|
}
|
|
}
|
|
LOG(WARNING) << "No node matching " << prefix << ":" << name << " was found";
|
|
return nullptr;
|
|
}
|
|
|
|
xmlNodePtr DepthFirstSearch(const xmlNodePtr parent, const char* name) {
|
|
return DepthFirstSearch(parent, "", name);
|
|
}
|
|
|
|
xmlNodePtr DepthFirstSearch(const xmlNodePtr parent, const char* prefix,
|
|
const char* name) {
|
|
if (parent == nullptr) {
|
|
LOG(ERROR) << "XML node was null";
|
|
return nullptr;
|
|
}
|
|
std::stack<xmlNodePtr> node_stack;
|
|
node_stack.push(parent);
|
|
while (!node_stack.empty()) {
|
|
const xmlNodePtr current_node = node_stack.top();
|
|
node_stack.pop();
|
|
if (strcmp(FromXmlChar(current_node->name), name) == 0) {
|
|
if (!prefix || strlen(prefix) == 0) {
|
|
return current_node;
|
|
}
|
|
if (current_node->ns && current_node->ns->prefix &&
|
|
strcmp(FromXmlChar(current_node->ns->prefix), prefix) == 0) {
|
|
return current_node;
|
|
}
|
|
}
|
|
std::stack<xmlNodePtr> stack_to_reverse;
|
|
for (xmlNodePtr child = current_node->children; child != nullptr;
|
|
child = child->next) {
|
|
stack_to_reverse.push(child);
|
|
}
|
|
while (!stack_to_reverse.empty()) {
|
|
node_stack.push(stack_to_reverse.top());
|
|
stack_to_reverse.pop();
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
} // namespace xml
|
|
} // namespace xmpmeta
|
|
} // namespace dynamic_depth
|