By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,171 Members | 943 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,171 IT Pros & Developers. It's quick & easy.

template class XML parser

P: n/a
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<ULONGaObjectCounts;

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<CAbilityBonusWalker(pAbilityBonu s);
if (Walker.traverse(Node))
{
pDataDefObject = (PDataDefObject) Walker.GetData();
}
}
break;

case DATA_TYPE_ABILITY_BONUS_OPTION:
{
PAbilityBonusOption pOption = NULL;
CGenericXMLWalker<CAbilityBonusOptionWalker(pOptio n);
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_NAA Vxml_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@PAV CAbilityBonusOption@@@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_no de@pug@@@Z)

error LNK2019: unresolved external symbol "public: bool __thiscall
CGenericXMLWalker<class CAbilityBonus>::traverse(class pug::xml_node
&)" (?traverse@?
$CGenericXMLWalker@VCAbilityBonus@@@@QAE_NAAVxml_n ode@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@PAVCAbili tyBonus@@@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.

Feb 22 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Cari Elf wrote:
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
{
[snip]
>
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.
Because template code should be placed in header files, all of it.

This is a FAQ

http://www.parashift.com/c++-faq-lit...html#faq-35.12

john
Feb 22 '07 #2

P: n/a
On Feb 22, 6:25 pm, John Harrison <john_androni...@hotmail.comwrote:
Cari Elf wrote:
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
{

[snip]
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.

Because template code should be placed in header files, all of it.

This is a FAQ

http://www.parashift.com/c++-faq-lit...html#faq-35.12

john
Thank you, I'll have to try that. None of the references I checked
mentioned that.

Feb 26 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.