// file: $isip/class/mmedia/XMLParser/xp_04.cc // version: $Id: xp_04.cc 10284 2005-10-27 20:52:14Z wholland $ #if defined(HAVE_EXPAT) // ISIP include files // #include "XMLParser.h" // method: markUnhandledTokens // // arguments: none // // return: a bool8 indicating status // // this method checks a vector of strings containing // the names of tokens which are allowed for a given // application, valid_values_d. All tokens whose values // are not in this vector are set to type UNHANDLED*. // // note that this does not directly apply to cdata type // token. whether a cdata token is handled depends // on whether the tags it's nested in are handled. // as int32 as a CDATA token is not nested in unhandled tags, // it is considered handled. // bool8 XMLParser::markUnhandledTokens() { // loop over all tokens in the token_vector_d // for(int32 i=0; i < token_vector_d.length(); i++) { // if a previous token exists, get its type // XMLToken::TYPE previous_token_type = XMLToken::NULL_TAG; if(i - 1 > 0) { previous_token_type = token_vector_d(i-1) .getType(); } // also, all CDATA tags contained within unhandled tags are considered // unhandled // if(token_vector_d(i).isA(XMLToken::CDATA) && previous_token_type == XMLToken::UNHANDLED) { // set the type of the token to UNHANDLED // token_vector_d(i).setType(XMLToken::UNHANDLED); } // if the value of the token is not present in the valid // values list, then it is unhandled // else if(!valid_values_d.contains (token_vector_d(i).getPointerToValue()) && !token_vector_d(i).isA(XMLToken::CDATA)) { // set the type of the token to UNHANDLED // token_vector_d(i).setType(XMLToken::UNHANDLED); } } // end looping over token vector // indicate success // return true; } // method: removeUnhandledTokens // // arguments: none // // return: a bool8 indicating status // // this method removes all unhandled tokens and recomputes // the depths of all tokens stored in the parser. // bool8 XMLParser::removeUnhandledTokens() { // make sure that cdata content of the unhandled // tokens is removed as well // markUnhandledTokens(); // a vector to store the modified xml document, // which will only contain handled tags // Vector handled_vector; // loop over all tokens contained in the token vector // for(int32 i = 0; i < token_vector_d.length(); i++) { // if the token is not an unhandled one, copy it to the new // vector of handled tokens // if(token_vector_d(i).getType() != XMLToken::UNHANDLED) { handled_vector.concat(token_vector_d(i)); } } // reset the depths of the tokens // setTokenDepths(handled_vector); // set the new vector of handled tokens as the token_vector_d // setTokenVector(handled_vector); // indicate success // return true; } // method: setTokenDepths // // arguments: none // // return: a bool8 indicating status // // this method calculates and sets the depths of all xml // tokens within the token_vertex_vector_d // bool8 XMLParser::setTokenDepths() { // call the master method // XMLParser::setTokenDepths(getTokenVector()); // build a table of debugging information // if(debug_level_d > Integral::DETAILED) { debugTokenDepths(getTokenVector()); } // indicate success // return true; } // method: setTokenDepths // // arguments: // Vector token_vector: (input) a vector of XMLTokens // representing an XML document. // // returns: a bool8 indicating status // // this method loops over all tokens in the vector. When it // encounters a start tag, the depth of that start tag and // of all following tags is increased by one. When it // encounters an end tag, the depth of that end tag and of all // following tags is decreased by one. Unhandled tags, combined // start and end tags, and CDATA tags do not affect the depth. // const bool8 XMLParser::setTokenDepths(Vector& token_vector_a) { // declare a variable to store the current depth in the document // int32 token_depth = 0; // loop over all tokens in the vector // for(int32 i=0; i < token_vector_a.length(); i++) { // start tags increase the depth // if(token_vector_a(i).isA(XMLToken::START_TAG)) { token_vector_a(i).setDepth(++token_depth); } // end tags decrease the depth // else if (token_vector_a(i).isA(XMLToken::END_TAG)) { token_vector_a(i).setDepth(--token_depth); } // if this token is of type CDATA, UNHANDLED*, or // START_AND_END_TAG // else { token_vector_a(i).setDepth(token_depth); } } // indicate success // return true; } // method: debugTokenDepths // // arguments: // Vector token_vector: (input) a vector of xml // tokens (any xml document) // // return: a bool8 indicating status // // this method outputs the token vector, alongside the token // indices and token depths // const bool8 XMLParser::debugTokenDepths(Vector& token_vector_a) { // declare a variable to store the output depth of the token // (this is almost, but not quite the same as the conceptual // depth of the token) // int32 token_depth = 0; // strings to store debugging information // SysString column1; SysString column2; SysString column3; SysString header(L"XMLParser: parsed token information:\n"); header.concat(L"|input |depth | xml form of input"); SysString output(header); for(int32 j = 0; j < token_vector_a.length(); j++) { token_depth = token_vector_a(j).getDepth(); column1.assign(j, L"%-6d"); column2.assign(token_depth, L"%-6d"); if(token_vector_a(j).isA(XMLToken::START_TAG)) { // adjust the depth for proper display (visual depth is different // from logical depth) // token_depth--; } column3.assign(getIndent(token_depth)); column3.concat(token_vector_a(j).toXML()); output.concat(L"\n|"); output.concat(column1); output.concat(L"|"); output.concat(column2); output.concat(L"|"); output.concat(column3); } // output the table // Console::put(output); // indicate success // return true; } #endif