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() );
 }
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
Archivo: xml.cpp Proyecto: dcdelia/mcvm
	/***************************************************************
	* 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);
	}