/* * Consume zero or more XMLTokens up to and including the corresponding * end XML element or EOF. */ void XMLInputStream::skipPastEnd (const XMLToken& element) { if ( element.isEnd() ) return; while ( isGood() && !peek().isEndFor(element) ) next(); next(); }
unsigned int XMLTokenizer::determineNumSpecificChildren(bool & valid, const std::string& qualifier, const std::string& container) { valid = false; unsigned int numQualifiers = 0; size_t size = mTokens.size(); if (size < 2) { return numQualifiers; } unsigned int depth = 0; unsigned int index = 0; std::string name; std::string prevName = ""; std::string rogueTag = ""; XMLToken next = mTokens.at(index); name = next.getName(); if (next.isStart() == true && next.isEnd() == true && name == qualifier && index < size) { numQualifiers++; index++; next = mTokens.at(index); } bool cleanBreak = false; while (index < size-2) { // skip any text elements while(next.isText() == true && index < size-1) { index++; next = mTokens.at(index); } if (next.isEnd() == true) { if (next.getName() == container) { valid = true; break; } //else if (!rogueTag.empty() && next.getName() == rogueTag) //{ // index++; // next = mTokens.at(index); // break; //} } // iterate to first start element while (next.isStart() == false && index < size-1) { index++; next = mTokens.at(index); } if (next.isStart() == true && next.isEnd() == true) { if (qualifier.empty() == true) { // if we are not looking for a specifc element then // we may have a child that is a start and end // such as <true/> numQualifiers++; } index++; if (index < size) { next = mTokens.at(index); continue; } } // check we have not reached the end // this would be a bad place if we have so set num children to zero if (index == size) { numQualifiers = 0; break; } // record the name of the start element name = next.getName(); // need to deal with the weird situation where someone has used a tag // after the piece but before the next correct element //if (container == "piecewise") //{ // if (prevName == "piece") // { // if (name != "piece" && name != "otherwise") // { // rogueTag = name; // index++; // next = mTokens.at(index); // continue; // } // } //} if (qualifier.empty() == true || name == qualifier) { numQualifiers++; } // index++; // check we have not reached the end if (index+1 == size) { numQualifiers = 0; break; } else { index++; next = mTokens.at(index); } // iterate to the end of </name> // checking that we have not got a nested element <name></name> cleanBreak = false; while (index < size-1) { if (next.isStart() == true && next.getName() == name) { depth++; } if (next.isEnd() == true && next.getName() == name) { if (depth == 0) { cleanBreak = true; break; } else { depth--; } } index++; if (index < size) { next = mTokens.at(index); } } prevName = name; index++; if (index < size) { next = mTokens.at(index); } } // we might have hit the end of the loop and the end of the correct tag if (valid == false && cleanBreak == true) { if (index >= size-2 && next.isEnd() == true && next.getName() == container) { valid = true; } } return numQualifiers; }
unsigned int XMLTokenizer::determineNumberChildren(bool & valid, const std::string element) { valid = false; unsigned int numChildren = 0; std::string closingTag = element; bool forcedElement = true; if (closingTag.empty() == true) { closingTag = "apply"; forcedElement = false; } // if there is only one token there cannot be any children size_t size = mTokens.size(); if (size < 2) { return numChildren; } // we assume that the first unread token is a // function and that at some point in the // list of tokens we will hit the end of the // element for that function // need to count the number of starts unsigned int index = 0; XMLToken firstUnread = mTokens.at(index); while (firstUnread.isText() && index < size - 1) { // skip any text index++; firstUnread = mTokens.at(index); } // if we have an apply the firstToken should be a function // that is both a start and an end // unless we are reading a user function // or a csymbol // if the tag is not a start and an end this is an error // we want to exit // but be happy that the read is ok // and the error gets logged elsewhere if (closingTag == "apply") { std::string firstName = firstUnread.getName(); if (firstName != "ci" && firstName != "csymbol") { if (firstUnread.isStart() != true || (firstUnread.isStart() == true && firstUnread.isEnd() != true)) { valid = true; return numChildren; } } } index = 1; if (forcedElement == true) { index = 0; } unsigned int depth = 0; std::string name; bool cleanBreak = false; XMLToken next = mTokens.at(index); while (index < size-2) { // skip any text elements while(next.isText() == true && index < size-1) { index++; next = mTokens.at(index); } if (next.isEnd() == true && next.getName() == closingTag) { valid = true; break; } // iterate to first start element while (next.isStart() == false && index < size-1) { index++; next = mTokens.at(index); } // check we have not reached the end // this would be a bad place if we have so set num children to zero if (index == size) { numChildren = 0; break; } // record the name of the start element name = next.getName(); numChildren++; // index++; // check we have not reached the end if (index + 1 == size) { numChildren = 0; break; } else if (next.isEnd() == false) { index++; if (index < size) { next = mTokens.at(index); } else { break; } } // iterate to the end of </name> // checking that we have not got a nested element <name></name> cleanBreak = false; while (index < size-1) { if (next.isStart() == true && next.isEnd() == false && next.getName() == name) { depth++; } if (next.isEnd() == true && next.getName() == name) { if (depth == 0) { cleanBreak = true; break; } else { depth--; } } index++; next = mTokens.at(index); } index++; if (index < size) { next = mTokens.at(index); } } // we might have hit the end of the loop and the end of the correct tag // but the loop hits before it can record that it was valid if (valid == false && cleanBreak == true) { if (index >= size-2 && next.isEnd() == true && next.getName() == closingTag) { valid = true; } } return numChildren; }