Ejemplo n.º 1
0
/***********************************************************************//**
 * @brief Process markup segment
 *
 * @param[in] current Handle to current node.
 * @param[in] segment Segment string.
 *
 * Process markup segment.
 ***************************************************************************/
void GXml::process_markup(GXmlNode** current, const std::string& segment)
{
    // Determine segment tag type
    MarkupType type = get_markuptype(segment);

    // Do tag specific processing
    switch (type) {

    // Handle element start tag
    case MT_ELEMENT_START:
        {
            // Create new element node, set it's parent, append it to the
            // current node and make it the current node
            GXmlElement element(segment);
            element.parent(*current);
            (*current)->append(element);
            int last = (*current)->size() - 1;
            (*current) = (*(*current))[last];
        }
        break;

    // Handle element end tag
    case MT_ELEMENT_END:
        {
            // Check if we expect an element end tag
            if ((*current)->type() != GXmlNode::NT_ELEMENT) {
                throw GException::xml_syntax_error(G_PROCESS, segment,
                      "unexpected element end tag encountered");
            }

            // Check if we have the correct end tag
            GXmlElement* element = (GXmlElement*)(*current);
            element->parse_stop(segment);

            // Set current node pointer back to parent of the current node
            (*current) = element->parent();
        }
        break;

    // Append empty-element tag
    case MT_ELEMENT_EMPTY:
        {
            GXmlElement element(segment.substr(1,segment.length()-3));
            element.parent(*current);
            (*current)->append(element);
        }
        break;

    // Append comment markup
    case MT_COMMENT:
        {
            GXmlComment comment(segment);
            (*current)->append(comment);
        }
        break;

    // Declaration markup
    case MT_DECLARATION:
        {
            // Verify if declaration tag is allowed
            if (*current != &m_root) {
                throw GException::xml_syntax_error(G_PROCESS, segment,
                      "unexpected declaration markup encountered");
            }
            if (!m_root.is_empty()) {
                throw GException::xml_syntax_error(G_PROCESS, segment,
                      "declaration markup only allowed in first line");
            }

            // Create temporary element to read in declaration attributes
            GXmlElement* element = new GXmlElement(segment);
            size_t       pos     = 5;
            while (pos != std::string::npos) {
                element->parse_attribute(&pos, segment);
            }

            // Set attribute values
            std::string version    = element->attribute("version");
            std::string encoding   = element->attribute("encoding");
            std::string standalone = element->attribute("standalone");
            if (version.length() > 0) {
                m_root.version(version);
            }
            if (encoding.length() > 0) {
                m_root.encoding(encoding);
            }
            if (standalone.length() > 0) {
                m_root.standalone(standalone);
            }

            // Delete temporary element
            delete element;
        }
        break;

    // Processing tag
    case MT_PROCESSING:
        {
            GXmlPI pi(segment);
            (*current)->append(pi);
        }
        break;

    // Invalid tag, throw an error
    case MT_INVALID:
        throw GException::xml_syntax_error(G_PROCESS, segment, "invalid tag");
        break;
    }

    // Return
    return;
}