Esempio n. 1
0
/*
 * 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;
}