示例#1
0
static void push_node(lua_State *L, const GumboNode *node) {
    luaL_checkstack(L, 10, "Unable to allocate Lua stack space");
    switch (node->type) {
    case GUMBO_NODE_ELEMENT: {
        const GumboElement *element = &node->v.element;
        lua_createtable(L, 0, 7);
        set_tag(L, element);
        set_sourcepos(L, element->start_pos);
        if (node->parse_flags != GUMBO_INSERTION_NORMAL) {
            set_integer(L, "parseFlags", node->parse_flags);
        }
        set_attributes(L, &element->attributes);
        set_children(L, &element->children, 1);
        setmetatable(L, Element);
        return;
    }
    case GUMBO_NODE_TEMPLATE: {
        const GumboElement *element = &node->v.element;
        lua_createtable(L, 0, 8);
        set_literal(L, "localName", "template");
        set_sourcepos(L, element->start_pos);
        set_attributes(L, &element->attributes);
        lua_createtable(L, 0, 0);
        setmetatable(L, NodeList);
        lua_setfield(L, -2, "childNodes");
        lua_createtable(L, 0, 1);
        set_children(L, &element->children, 1);
        setmetatable(L, DocumentFragment);
        lua_setfield(L, -2, "content");
        setmetatable(L, Element);
        return;
    }
    case GUMBO_NODE_TEXT:
        create_text_node(L, &node->v.text, Text);
        return;
    case GUMBO_NODE_WHITESPACE:
        create_text_node(L, &node->v.text, Text);
        set_literal(L, "type", "whitespace");
        return;
    case GUMBO_NODE_COMMENT:
        create_text_node(L, &node->v.text, Comment);
        return;
    case GUMBO_NODE_CDATA:
        create_text_node(L, &node->v.text, Text);
        set_literal(L, "type", "cdata");
        return;
    default:
        luaL_error(L, "GumboNodeType value out of bounds: %d", node->type);
        return;
    }
}
示例#2
0
static void push_node(lua_State *L, const GumboNode *node) {
    luaL_checkstack(L, 10, "element nesting too deep");
    switch (node->type) {
    case GUMBO_NODE_DOCUMENT: {
        const GumboDocument *document = &node->v.document;
        lua_createtable(L, document->children.length, 4);
        add_literal(L, "type", "document");
        add_string(L, "quirks_mode", quirksmap[document->doc_type_quirks_mode]);
        if (document->has_doctype) {
            lua_createtable(L, 0, 3);
            add_string(L, "name", document->name);
            add_string(L, "publicId", document->public_identifier);
            add_string(L, "systemId", document->system_identifier);
            lua_setfield(L, -2, "doctype");
        }
        add_children(L, &document->children);
        return;
    }
    case GUMBO_NODE_ELEMENT: {
        const GumboElement *element = &node->v.element;
        lua_createtable(L, element->children.length, 7);
        lua_getfield(L, LUA_REGISTRYINDEX, "gumbo.element");
        lua_setmetatable(L, -2);
        add_tag(L, element);
        add_string(L, "tag_namespace", tagnsmap[element->tag_namespace]);
        add_integer(L, "line", element->start_pos.line);
        add_integer(L, "column", element->start_pos.column);
        add_integer(L, "offset", element->start_pos.offset);
        add_parseflags(L, node->parse_flags);
        add_attributes(L, &element->attributes);
        add_children(L, &element->children);
        return;
    }
    case GUMBO_NODE_TEXT:
        create_text_node(L, &node->v.text);
        add_literal(L, "type", "text");
        return;
    case GUMBO_NODE_COMMENT:
        create_text_node(L, &node->v.text);
        add_literal(L, "type", "comment");
        return;
    case GUMBO_NODE_CDATA:
        create_text_node(L, &node->v.text);
        add_literal(L, "type", "cdata");
        return;
    case GUMBO_NODE_WHITESPACE:
        create_text_node(L, &node->v.text);
        add_literal(L, "type", "whitespace");
        return;
    }
}
示例#3
0
	std::vector<DomNode> DomDocument::load(
		IODevice &input,
		bool eat_whitespace,
		DomNode insert_point)
	{
		clear_all();

		XMLTokenizer tokenizer(input);
		tokenizer.set_eat_whitespace(eat_whitespace);

		if (insert_point.is_element() == false)
			insert_point = *this;

		std::vector<DomNode> node_stack;
		node_stack.push_back(insert_point);

		std::vector<DomNode> result;
		try
		{
			XMLToken cur_token;
			tokenizer.next(&cur_token);
			while (cur_token.type != XMLToken::NULL_TOKEN)
			{
				switch (cur_token.type)
				{
				case XMLToken::TEXT_TOKEN:
					node_stack.back().append_child(create_text_node(cur_token.value));
					if (node_stack.back() == insert_point)
						result.push_back(node_stack.back().get_last_child());
					break;

				case XMLToken::CDATA_SECTION_TOKEN:
					node_stack.back().append_child(create_cdata_section(cur_token.value));
					if (node_stack.back() == insert_point)
						result.push_back(node_stack.back().get_last_child());
					break;

				case XMLToken::ELEMENT_TOKEN:
					if (cur_token.variant != XMLToken::END)
					{
						DomString namespace_uri = DomDocument_Impl::find_namespace_uri(cur_token.name, cur_token, node_stack.back());
						DomElement element = create_element_ns(namespace_uri, cur_token.name);
						node_stack.back().append_child(element);
						if (node_stack.back() == insert_point)
							result.push_back(node_stack.back().get_last_child());

						int size = (int)cur_token.attributes.size();
						for (int i = 0; i < size; i++)
						{
							XMLToken::Attribute &attribute = cur_token.attributes[i];
							DomString attribute_namespace_uri = DomDocument_Impl::find_namespace_uri(attribute.first, cur_token, node_stack.back());
							element.set_attribute_ns(
								attribute_namespace_uri,
								attribute.first,
								attribute.second);
						}

						if (cur_token.variant == XMLToken::BEGIN)
							node_stack.push_back(element);
					}
					else
					{
						node_stack.pop_back();
						if (node_stack.empty()) throw Exception("Malformed XML tree!");
					}
					break;

				case XMLToken::NULL_TOKEN:
					break;

				case XMLToken::ENTITY_REFERENCE_TOKEN:
					break;

				case XMLToken::ENTITY_TOKEN:
					break;

				case XMLToken::COMMENT_TOKEN:
					node_stack.back().append_child(create_comment(cur_token.value));
					if (node_stack.back() == insert_point)
						result.push_back(node_stack.back().get_last_child());
					break;

				case XMLToken::DOCUMENT_TYPE_TOKEN:
					break;

				case XMLToken::NOTATION_TOKEN:
					break;

				case XMLToken::PROCESSING_INSTRUCTION_TOKEN:
					node_stack.back().append_child(create_processing_instruction(cur_token.name, cur_token.value));
					if (node_stack.back() == insert_point)
						result.push_back(node_stack.back().get_last_child());
					break;
				}

				tokenizer.next(&cur_token);
			}
		}
		catch (const Exception& e)
		{
			for (auto & elem : result)
			{
				insert_point.remove_child(elem);
			}
			throw;
		}
		return result;
	}
示例#4
0
	DomNode DomDocument::import_node(const DomNode &node, bool deep)
	{
		DomNode imported_node;
		switch (node.get_node_type())
		{
		case NULL_NODE:
			return imported_node;
		case ELEMENT_NODE:
			imported_node = create_element_ns(node.get_namespace_uri(), node.get_node_name());
			break;
		case ATTRIBUTE_NODE:
			imported_node = create_attribute_ns(node.get_namespace_uri(), node.get_node_name());
			imported_node.set_node_value(node.get_node_value());
			break;
		case TEXT_NODE:
			imported_node = create_text_node(node.get_node_value());
			break;
		case CDATA_SECTION_NODE:
			imported_node = create_cdata_section(node.get_node_value());
			break;
		case ENTITY_REFERENCE_NODE:
			imported_node = create_entity_reference(node.get_node_name());
			break;
		case ENTITY_NODE:
			return imported_node;
		case PROCESSING_INSTRUCTION_NODE:
			imported_node = create_processing_instruction(node.to_processing_instruction().get_target(), node.to_processing_instruction().get_data());
			break;
		case COMMENT_NODE:
			imported_node = create_comment(node.get_node_value());
			break;
		case DOCUMENT_NODE:
			imported_node = create_document_fragment();
			break;
		case DOCUMENT_TYPE_NODE:
			return imported_node;
		case DOCUMENT_FRAGMENT_NODE:
			imported_node = create_document_fragment();
			break;
		case NOTATION_NODE:
			return imported_node;
		}

		if (node.is_element())
		{
			DomElement import_element = imported_node.to_element();
			DomNamedNodeMap node_attributes = node.get_attributes();
			int size = node_attributes.get_length();
			for (int index = 0; index < size; index++)
			{
				DomNode attr = node_attributes.item(index);
				import_element.set_attribute_node_ns(import_node(attr, deep).to_attr());
			}
		}

		if (deep)
		{
			DomNode cur = node.get_first_child();
			while (!cur.is_null())
			{
				imported_node.append_child(import_node(cur, true));
				cur = cur.get_next_sibling();
			}
		}

		return imported_node;
	}