template class XML parser
I wrote a template class that inherits from the PUG xml_tree_walker
class so that I can load data from any XML file without having to
write a parser for each one.
template <class T>
class CGenericXMLWalker : public pug::xml_tree_walker
{
T* m_pData;
public:
CGenericXMLWalker(T* pDataIn);
~CGenericXMLWalker();
T* GetData() {m_pData->AddRef(); return m_pData;}
//Traversal begin callback.
bool begin(pug::xml_node& node);
//Traversal node callback; cumulatively outputs a simple document
outline.
bool for_each(pug::xml_node& node);
//Traversal end callback.
bool end(pug::xml_node& node);
bool traverse(pug::xml_node& node);
VOID AddNodeAttributes(pug::xml_node& node);
};
It calls a function that I have defined in another file that accepts
an xml node and determines which class to pass to the template based
on the name of the xml node.
PDataDefObject TraverseDataType(pug::xml_node & Node)
{
if (Node.empty() || Node.has_attribute( "NoParse" ) )
return NULL;
PDataDefObject pDataDefObject = NULL;
static TagMap mapObjectTypes;
static std::vector<ULONG> aObjectCounts;
if (mapObjectTypes.empty())
{
// fill map here
mapObjectTypes["AbilityBonus"] = DATA_TYPE_ABILITY_BONUS;
mapObjectTypes["AbilityBonusOptions"] =
DATA_TYPE_ABILITY_BONUS_OPTION;
// etc
}
if (aObjectCounts.empty())
{
aObjectCounts.assign(NUM_ELEMENTAL_DATA_TYPES, 0);
}
ULONG ulDataType = UNKNOWN_ELEMENTAL_DATA_TYPE;
ULONG ulObjectCount = 0;
TagMap::iterator itFind = mapObjectTypes.find(Node.name());
if (itFind != mapObjectTypes.end())
{
ulDataType = (*itFind).second;
ulObjectCount = aObjectCounts[ulDataType];
switch(ulDataType)
{
case DATA_TYPE_ABILITY_BONUS:
{
PAbilityBonus pAbilityBonus = NULL;
CGenericXMLWalker<CAbilityBonus> Walker(pAbilityBonus);
if (Walker.traverse(Node))
{
pDataDefObject = (PDataDefObject) Walker.GetData();
}
}
break;
case DATA_TYPE_ABILITY_BONUS_OPTION:
{
PAbilityBonusOption pOption = NULL;
CGenericXMLWalker<CAbilityBonusOption> Walker(pOption);
if (Walker.traverse(Node))
{
pDataDefObject = (PDataDefObject) Walker.GetData();
}
}
break;
};
}
if (pDataDefObject)
{
pDataDefObject->SetDataTypeString(Node.name());
pDataDefObject->SetDataType(ulDataType);
++ulObjectCount;
aObjectCounts[ulDataType] = ulObjectCount;
}
return pDataDefObject;
}
It compiles OK, but I get linker errors:
error LNK2019: unresolved external symbol "public: virtual __thiscall
CGenericXMLWalker<class CAbilityBonusOption>::~CGenericXMLWalker<class
CAbilityBonusOption>(void)" (??1?
$CGenericXMLWalker@VCAbilityBonusOption@@@@UAE@XZ) referenced in
function "class CDataDefObject * __cdecl TraverseDataType(class
pug::xml_node &)" (?
TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
error LNK2019: unresolved external symbol "public: bool __thiscall
CGenericXMLWalker<class CAbilityBonusOption>::traverse(class
pug::xml_node &)" (?traverse@?
$CGenericXMLWalker@VCAbilityBonusOption@@@@QAE_NAAVxml_node@pug@@@Z)
referenced in function "class CDataDefObject * __cdecl
TraverseDataType(class pug::xml_node &)" (?
TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
error LNK2019: unresolved external symbol "public: __thiscall
CGenericXMLWalker<class CAbilityBonusOption>::CGenericXMLWalker<class
CAbilityBonusOption>(class CAbilityBonusOption *)" (??0?
$CGenericXMLWalker@VCAbilityBonusOption@@@@QAE@PAVCAbilityBonusOption@@@Z)
referenced in function "class CDataDefObject * __cdecl
TraverseDataType(class pug::xml_node &)" (?
TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
error LNK2019: unresolved external symbol "public: virtual __thiscall
CGenericXMLWalker<class CAbilityBonus>::~CGenericXMLWalker<class
CAbilityBonus>(void)" (??1?
$CGenericXMLWalker@VCAbilityBonus@@@@UAE@XZ) referenced in function
"class CDataDefObject * __cdecl TraverseDataType(class pug::xml_node
&)" (?TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
error LNK2019: unresolved external symbol "public: bool __thiscall
CGenericXMLWalker<class CAbilityBonus>::traverse(class pug::xml_node
&)" (?traverse@?
$CGenericXMLWalker@VCAbilityBonus@@@@QAE_NAAVxml_node@pug@@@Z)
referenced in function "class CDataDefObject * __cdecl
TraverseDataType(class pug::xml_node &)" (?
TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
error LNK2019: unresolved external symbol "public: __thiscall
CGenericXMLWalker<class CAbilityBonus>::CGenericXMLWalker<class
CAbilityBonus>(class CAbilityBonus *)" (??0?
$CGenericXMLWalker@VCAbilityBonus@@@@QAE@PAVCAbilityBonus@@@Z)
referenced in function "class CDataDefObject * __cdecl
TraverseDataType(class pug::xml_node &)" (?
TraverseDataType@@YAPAVCDataDefObject@@AAVxml_node@pug@@@Z)
: fatal error LNK1120: 6 unresolved externals
I've got all the proper files included, all my classes are defined,
and I just can't figure out why it's getting the linker errors. Does
anyone have any ideas?
Thanks.