179 lines
4.4 KiB
C++
179 lines
4.4 KiB
C++
/*
|
|
Copyright (C) 2005-2006 Feeling Software Inc.
|
|
MIT License: http://www.opensource.org/licenses/mit-license.php
|
|
*/
|
|
/*
|
|
Based on the FS Import classes:
|
|
Copyright (C) 2005-2006 Feeling Software Inc
|
|
Copyright (C) 2005-2006 Autodesk Media Entertainment
|
|
MIT License: http://www.opensource.org/licenses/mit-license.php
|
|
*/
|
|
|
|
#include "StdAfx.h"
|
|
#include "FUtils/FUXmlParser.h"
|
|
|
|
#define xmlT(a) (const xmlChar*) (a)
|
|
|
|
namespace FUXmlParser
|
|
{
|
|
// Returns the first child node of a given type
|
|
xmlNode* FindChildByType(xmlNode* parent, const char* type)
|
|
{
|
|
if (parent != NULL)
|
|
{
|
|
for (xmlNode* child = parent->children; child != NULL; child = child->next)
|
|
{
|
|
if (child->type == XML_ELEMENT_NODE)
|
|
{
|
|
if (IsEquivalent(child->name, type)) return child;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// return the first child node of a given name
|
|
xmlNode* FindChildByName(xmlNode* parent, const char* name)
|
|
{
|
|
if (parent != NULL)
|
|
{
|
|
for (xmlNode* child = parent->children; child != NULL; child = child->next)
|
|
{
|
|
if (child->type == XML_ELEMENT_NODE)
|
|
{
|
|
string str_name = ReadNodeProperty(child, "name");
|
|
if (str_name == name) return child;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// return the first child node of a given property value
|
|
xmlNode* FindChildByProperty(xmlNode* parent, const char* prop, const char* val )
|
|
{
|
|
if (parent != NULL)
|
|
{
|
|
for (xmlNode* child = parent->children; child != NULL; child = child->next)
|
|
{
|
|
string str_pop = ReadNodeProperty(child, prop);
|
|
if (str_pop == val) return child;
|
|
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// return the first node in list of a given property
|
|
xmlNode* FindNodeInListByProperty(xmlNodeList list, const char* property, const char* prop)
|
|
{
|
|
for (xmlNodeList::iterator it = list.begin(); it != list.end(); ++it)
|
|
{
|
|
xmlNode* element = *it;
|
|
string str_prop = ReadNodeProperty(element, property);
|
|
if (str_prop == prop) return element;
|
|
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
// Retrieves all the child nodes of a given type
|
|
void FindChildrenByType(xmlNode* parent, const char* type, xmlNodeList& nodes)
|
|
{
|
|
if (parent != NULL)
|
|
{
|
|
for (xmlNode* child = parent->children; child != NULL; child = child->next)
|
|
{
|
|
if (child->type == XML_ELEMENT_NODE)
|
|
{
|
|
if (IsEquivalent(child->name, type)) nodes.push_back(child);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns whether the given node has the given property
|
|
bool HasNodeProperty(xmlNode* node, const char* property)
|
|
{
|
|
xmlAttr* attribute = xmlHasProp(node, xmlT(property));
|
|
return attribute != NULL;
|
|
}
|
|
|
|
// Returns the string value of a node's property
|
|
string ReadNodeProperty(xmlNode* node, const char* property)
|
|
{
|
|
string ret;
|
|
if (node != NULL && property != NULL)
|
|
{
|
|
xmlChar* data = xmlGetProp(node, xmlT(property));
|
|
if (data != NULL) ret = (const char*) data;
|
|
xmlFree(data);
|
|
}
|
|
|
|
// Process the string for special characters
|
|
XmlToString(ret);
|
|
return ret;
|
|
}
|
|
|
|
// Returns the CRC value of a node's property
|
|
FUCrc32::crc32 ReadNodePropertyCRC(xmlNode* node, const char* property)
|
|
{
|
|
FUCrc32::crc32 ret = 0;
|
|
if (node != NULL && property != NULL)
|
|
{
|
|
xmlChar* data = xmlGetProp(node, xmlT(property));
|
|
if (data != NULL) ret = FUCrc32::CRC32((const char*) data);
|
|
xmlFree(data);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Returns the text content directly attached to a node
|
|
const char* ReadNodeContentDirect(xmlNode* node)
|
|
{
|
|
if (node == NULL || node->children == NULL
|
|
|| node->children->type != XML_TEXT_NODE || node->children->content == NULL) return "";
|
|
return (const char*) node->children->content;
|
|
}
|
|
|
|
// Returns the inner text content of a node
|
|
string ReadNodeContentFull(xmlNode* node)
|
|
{
|
|
string ret;
|
|
if (node != NULL)
|
|
{
|
|
xmlChar* content = xmlNodeGetContent(node);
|
|
ret = (const char*) content;
|
|
xmlFree(content);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Convert a XML string to a text string: handles the '%' character
|
|
void XmlToString(string& s)
|
|
{
|
|
if (s.find('%') == string::npos) return;
|
|
|
|
// Replace all the '%XX' characters by the equivalent hex value
|
|
const char* original = s.c_str();
|
|
uint32 length = (uint32) s.length();
|
|
char* copy = new char[length],* p = copy;
|
|
for (uint32 i = 0; i < length; ++i, ++p)
|
|
{
|
|
char c = original[i];
|
|
if (c != '%' || i >= length - 2) *p = c;
|
|
else
|
|
{
|
|
char* dummy;
|
|
p[0] = original[i + 1]; p[1] = original[i + 2]; p[2] = 0;
|
|
uint32 v = strtoul(p, &dummy, 16);
|
|
*p = (char) v;
|
|
i += 2;
|
|
}
|
|
}
|
|
*p = 0;
|
|
s = copy;
|
|
}
|
|
};
|