Files
bullet3/Extras/FCollada/FUtils/FUXmlParser.cpp
2006-05-25 19:18:29 +00:00

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;
}
};