inline bool AsciiXmlParser::readNextElement() /* this reads in the entire next XML element. false is returned if the end * of the text was reached before a new XML element could be found (or if * no end for the next element could be found). */ { return ( discardToNextTag() && parseTagName( elementName ) && parseAttributes() && recordToEndOfElement() ); }
bool parseTagOrWord() { if (yytoken == LEFT_ANGLE) { nextToken(); if (! parseTagName()) return false; if (yytoken != RIGHT_ANGLE) return false; nextToken(); fprintf (stderr, "*** found a tag\n"); } else if (yytoken == ANY) { nextToken(); } else { return false; } return true; }
/*************************************************************** * Function: Parser::parseElement() * Purpose : Parse an XML element * Initial : Maxime Chevalier-Boisvert on October 20, 2008 **************************************************************** Revisions and bug fixes: */ Element* Parser::parseElement(const std::string& xmlString, size_t& charIndex, const PosVector& positions) { // If this XML element does not begin appropriately if (xmlString[charIndex] != '<') { // Throw an exception throw ParseError("Invalid XML element opening", positions[charIndex]); } // Get the current text position const TextPos& textPos = positions[charIndex]; // Move to the next character ++charIndex; // Declare variables for the current and next characters unsigned char thisChar; unsigned char nextChar; // Declare a map of attributes std::map<std::string, std::string> attributes; // Declare a vector of children nodes std::vector<Node*> children; // Declare a boolean to indicate if this is a leaf tag bool isLeaf = false; // Parse the tag name std::string name = parseTagName(xmlString, charIndex, positions); // Move to the next character ++charIndex; // For each character for (;; ++charIndex) { // If we are past the length of the input stream if (charIndex > xmlString.length()) { // Throw an exception throw ParseError("Unexpected end of stream inside opening tag", positions[charIndex]); } // Update the current and next characters thisChar = xmlString[charIndex]; nextChar = xmlString[charIndex + 1]; // If this is a space if (isspace(thisChar)) { // Skip the space continue; } // If this is the end of the opening tag if (thisChar == '>') { // Move to the next character ++charIndex; // End this loop break; } // If this character is a leaf tag if (thisChar == '/' && nextChar == '>') { // Set the leaf tag flag isLeaf = true; // Skip this character ++charIndex; // End this loop break; } // If this character is alphanumeric if (isalnum(thisChar)) { // Parse this attribute std::pair<std::string, std::string> attribute = parseAttribute(xmlString, charIndex, positions); // If another attribute with this name was already parsed if (attributes.find(attribute.first) != attributes.end()) { // Throw an exception throw ParseError("Duplicate attribute name: " + attribute.first, positions[charIndex]); } // Add this attribute to the map attributes[attribute.first] = attribute.second; // Move to the next character continue; } // If this character was not recognized, throw an exception throw ParseError("Invalid character inside opening tag", positions[charIndex]); } // If this is not a leaf tag if (!isLeaf) { // For each character for (;; ++charIndex) { // If we are past the length of the input stream if (charIndex > xmlString.length()) { // Throw an exception throw ParseError("Unexpected end of stream inside tag", positions[charIndex]); } // Update the current and next characters thisChar = xmlString[charIndex]; nextChar = xmlString[charIndex + 1]; // If this is a space if (isspace(thisChar)) { // Skip the space continue; } // If this is the beggining of the closing tag if (thisChar == '<' && nextChar == '/') { // Skip these characters charIndex += 2; // Break out of this loop break; } // Parse the child node at this point Node* pChildNode = parseNode(xmlString, charIndex, positions); // Add the child node to the list children.push_back(pChildNode); } // Parse the closing tag name std::string closingName = parseTagName(xmlString, charIndex, positions); // If the tag names do not match if (name != closingName) { // Throw an exception throw ParseError("Unmatching closing tag for \"" + name + "\" : \"/" + closingName + "\"", positions[charIndex]); } // Move to the next character ++charIndex; // If the closing tag does not end properly if (xmlString[charIndex] != '>') { // Throw an exception throw ParseError("Malformed closing tag", positions[charIndex]); } } // Create and return a new XML element with the parsed information return new Element(name, attributes, children, textPos, isLeaf); }