Problem Iterating through XML tree - nested tags

101 views
Skip to first unread message

rah2435

unread,
Oct 22, 2009, 10:29:01 AM10/22/09
to TinyXML++
I hope someone can point me in the right direction...I'm under a
deadline to get this project done and parsing this XML is just a small
part of what I need done. i decided to use tinyXML++ since it looked
easy to use and small enough to fit easily into my project. However,
I seem to be experiencing some difficulty iterating through nested
tags in my config file XML using ticpp...

the XML looks like this

<KOP_LOAD>
-
<PRODUCT name="DEFAULT">
<PATHSFOR855 INCOMING="/source/pita/Test_load_files"
ARCHIVE="/source/pita/Archive"/>
<PATHSFOR866 OUTGOING="" ARCHIVE=""/>
-
<EDI855HEADER>
<FIELD name="Data_type_code" type="NUMBER" length="2" required="Yy"/
>
<FIELD name="Contract_number" type="CHAR" length="13" required="Y"/>
<FIELD name="Delivery_order_number" type="CHAR" length="4"
required="Y"/>
<FIELD name="Order_dt" type="DATE" length="10" required="Y"/>
<FIELD name="Ordering_dodaac" type="CHAR" length="6" required="Y"/>
<FIELD name="Ship_to_dodaac" type="CHAR" length="6" required="Y"/>
<FIELD name="cc_Custid" type="CHAR" length="5" required="C"/>
<FIELD name="PV_part_number" type="CHAR" length="48" required="C"/>
<FIELD name="Mfg_part_number" type="CHAR" length="48" required="C"/>
<FIELD name="Mfg_name" type="CHAR" length="50" required="C"/>
<FIELD name="Nsn" type="CHAR" length="13" required="C"/>
<FIELD name="Item_description" type="CHAR" length="2048"
required="Y"/>
<FIELD name="Qty_ordered" type="NUMBER" length="12" required="Y"/>
<FIELD name="Unit_of_measure" type="CHAR" length="2" required="Y"/>
<FIELD name="Unburdened_unit_price" type="NUMBER" length="20"
required="Y"/>
<FIELD name="Burdened_unit_price" type="NUMBER" length="20"
required="Y"/>
<FIELD name="Unburdened_extended_price" type="NUMBER" length="20"
required="Y"/>
<FIELD name="Burdened_extended_price" type="NUMBER" length="20"
required="Y"/>
<FIELD name="Requisition_number" type="CHAR" length="17"
required="N"/>
<FIELD name="Signal_code" type="CHAR" length="1" required="Y"/>
<FIELD name="Funding_code" type="CHAR" length="2" required="Y"/>
<FIELD name="Project_code" type="CHAR" length="3" required="N"/>
<FIELD name="Order_type" type="CHAR" length="2" required="Y"/>
<FIELD name="Order_ID" type="CHAR" length="10" required="Y"/>
<FIELD name="Required_delivery_dt" type="CHAR" length="10"
required="Y"/>
<FIELD name="Priority_code" type="CHAR" length="1" required="Y"/>
<FIELD name="Contractor_control_number" type="CHAR" length="15"
required="Y"/>
<FIELD name="ACK_code" type="CHAR" length="2" required="C"/>
<FIELD name="ACK_required_delivery_dt_qualifier" type="CHAR"
length="3"
required="C"/>
<FIELD name="ACK_required_delivery_dt" type="CHAR" length="8"
required="C"/>
<FIELD name="MIPR" type="CHAR" length="40" required="Y"/>
<FIELD name="RQN" type="CHAR" length="48" required="C"/>
</EDI855HEADER>
</PRODUCT>
-
<PRODUCT name="MRO">
<EDI855HEADER>
</EDI855HEADER>
</PRODUCT>
<PRODUCT name="METALS"/>
<PRODUCT name="SPEC_OPS"/>
<PRODUCT name="FES"/>
<PRODUCT name="BIDWISER"/>
-
<DATABASE>
<LOGIN>pvrun</LOGIN>
<PASSWORD_FILE/>
<SID>PVFE</SID>
<HOST>localmachine</HOST>
<PREFIX>PVADM.</PREFIX>
</DATABASE>
-
<PIPES>
<PIPE id="MRO"/>
<PIPE id="SPEC_OPS"/>
<PIPE id="METALS"/>
<PIPE id="BIDWISER"/>
</PIPES>
</KOP_LOAD>


I want to get all the data from the FIELD tags....but the inner for
loop in my code never executes.
I couldn't find any examples of iterating through "nested" nodes - but
this would seem to make sense to me...

void Config::parse()
{

try
{
ticpp::Document config( this->m_filename );
config.LoadFile();
ticpp::Element *root_object = config.FirstChildElement
("KOP_LOAD");
ticpp::Iterator<ticpp::Element>
products(root_object->FirstChildElement("PRODUCT"),
"PRODUCT" );

// THIS LOOP WORKS
for ( ; products != products.end(); products++ )
{
string product = "";
products->GetAttributeOrDefault("name", &product, "");

if ( product == "DEFAULT" )
{
ticpp::Element *headerNode = products->FirstChildElement
("EDI855HEADER","EDI855HEADER");
if ( headerNode != NULL )
{

THIS LOOP FAILS:


for(ticpp::Iterator<ticpp::Element>
child(root_object->FirstChildElement("FIELD"),"FIELD"); child !=
child.end();
++child)
{
string type="";
int length=0;
string required="";
cout << "\nFIELD: " << child->GetText()<< endl;
child->GetAttributeOrDefault("type",&type,false);
cout << "\tType = " << type << endl;
child->GetAttributeOrDefault
("type",&length,false);
cout << "\tLength = " << length << endl;

child->GetAttributeOrDefault
("type",&required,false);
cout << "\tRequired = " << required << endl <<
endl;
}
}
}
}
}
catch(ticpp::Exception& error)
{
cerr << "Error: " << error.m_details << endl;
this->m_error = error.m_details;
}

Ryan Pusztai

unread,
Oct 22, 2009, 11:21:04 AM10/22/09
to ti...@googlegroups.com
The line
for(ticpp::Iterator<ticpp::Element>child(root_object->FirstChildElement("FIELD"),"FIELD"); child !=child.end();++child)
{
    ...
}
root_object (bolded) is plain wrong. There is not a first child element named "field" in that XML. That is under your 'headerNode'. Change the loop to

headerNode->FirstChildElement("FIELD"),"FIELD")

and you should be all set. Please not that I have not tested this, but I know the code you have is wrong and you need to track the Elements at the right level.
--
Regards,
Ryan

rah2435

unread,
Oct 22, 2009, 3:07:20 PM10/22/09
to TinyXML++
YES!!! Of course....duh! :)
this works.


thanks so much, i suppose this is what I get when I'm coding with
little sleep, lol!

Rich
> for(ticpp::Iterator<ticpp::Element>child(*root_object*->FirstChildElement("FIELD"),"FIELD");
Reply all
Reply to author
Forward
0 new messages