⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dom_document.cpp

📁 这是一款2d游戏引擎
💻 CPP
字号:
/*  $Id: dom_document.cpp,v 1.20 2004/01/02 10:37:41 mbn Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

#include "Core/precomp.h"
#include "API/Core/XML/dom_document.h"
#include "API/Core/XML/dom_document_type.h"
#include "API/Core/XML/dom_implementation.h"
#include "API/Core/XML/dom_element.h"
#include "API/Core/XML/dom_document_fragment.h"
#include "API/Core/XML/dom_text.h"
#include "API/Core/XML/dom_comment.h"
#include "API/Core/XML/dom_cdata_section.h"
#include "API/Core/XML/dom_processing_instruction.h"
#include "API/Core/XML/dom_attr.h"
#include "API/Core/XML/dom_entity_reference.h"
#include "API/Core/XML/dom_node_list.h"
#include "API/Core/XML/xml_tokenizer.h"
#include "API/Core/XML/xml_writer.h"
#include "API/Core/XML/xml_token.h"
#include "dom_document_generic.h"
#include <stack>

#include "API/Core/XML/xml_token_load.h"
#include "API/Core/XML/xml_token_save.h"
#include "API/Core/XML/xml_token_string.h"

/////////////////////////////////////////////////////////////////////////////
// CL_DomDocument construction:

CL_DomDocument::CL_DomDocument() : CL_DomNode(new CL_DomDocument_Generic)
{
}

CL_DomDocument::CL_DomDocument(CL_InputSource *input, bool delete_input, bool eat_whitespace)
: CL_DomNode(new CL_DomDocument_Generic)
{
	load(input, delete_input, eat_whitespace);
}

CL_DomDocument::CL_DomDocument(CL_DomNode_Generic *impl) : CL_DomNode(impl)
{
}

CL_DomDocument::~CL_DomDocument()
{
}

/////////////////////////////////////////////////////////////////////////////
// CL_DomDocument attributes:

CL_DomDocumentType CL_DomDocument::get_doctype()
{
	return CL_DomDocumentType(*this);
}

CL_DomImplementation CL_DomDocument::get_implementation()
{
	return CL_DomImplementation(*this);
}

CL_DomElement CL_DomDocument::get_document_element()
{
	CL_DomNode cur(impl->first_child);
	while (!cur.is_null())
	{
		if (cur.is_element()) return cur.to_element();
		cur = cur.get_next_sibling();
	}
	return CL_DomElement();
}

/////////////////////////////////////////////////////////////////////////////
// CL_DomDocument operations:

CL_DomElement CL_DomDocument::create_element(const std::string &tag_name)
{
	return CL_DomElement(*this, tag_name);
}

CL_DomDocumentFragment CL_DomDocument::create_document_fragment()
{
	return CL_DomDocumentFragment(*this);
}

CL_DomText CL_DomDocument::create_text_node(const std::string &data)
{
	return CL_DomText(*this, data);
}

CL_DomComment CL_DomDocument::create_comment(const std::string &data)
{
	return CL_DomComment(*this, data);
}

CL_DomCDATASection CL_DomDocument::create_cdata_section(const std::string &data)
{
	return CL_DomCDATASection(*this, data);
}

CL_DomProcessingInstruction CL_DomDocument::create_processing_instruction(
	const std::string &target,
	const std::string &data)
{
	return CL_DomProcessingInstruction(*this, target, data);
}

CL_DomAttr CL_DomDocument::create_attribute(const std::string &name)
{
	return CL_DomAttr(*this, name);
}

CL_DomEntityReference CL_DomDocument::create_entity_reference(const std::string &name)
{
	return CL_DomEntityReference(*this, name);
}

CL_DomNodeList CL_DomDocument::get_elements_by_tag_name(const std::string &tag_name)
{
	return CL_DomNodeList(*this, tag_name);
}

void CL_DomDocument::load(CL_InputSource *input, bool delete_input, bool eat_whitespace)
{
	CL_XMLTokenizer tokenizer(input, delete_input);
	tokenizer.set_eat_whitespace(eat_whitespace);

	std::stack<CL_DomNode> node_stack;
	node_stack.push(*this);
	
	CL_XMLTokenLoad cur_token = tokenizer.next();
	while (cur_token.get_type() != CL_XMLToken::NULL_TOKEN)
	{
		switch (cur_token.get_type())
		{
		case CL_XMLToken::TEXT_TOKEN:
			node_stack.top().append_child(create_text_node(cur_token.get_value()));
			break;
			
		case CL_XMLToken::CDATA_SECTION_TOKEN:
			node_stack.top().append_child(create_cdata_section(cur_token.get_value()));
			break;

		case CL_XMLToken::ELEMENT_TOKEN:
			if (cur_token.get_variant() != CL_XMLToken::END)
			{
				CL_DomElement element = create_element(cur_token.get_name());
				node_stack.top().append_child(element);
				
				//const std::vector< std::pair<std::string, std::string> > &attributes = cur_token.get_attributes();
				int size = cur_token.get_attributes_number();
				for (int i=0; i<size; i++)
				{
//					std::pair<std::string, std::string> attribute(cur_token.get_attribute(i));
					std::pair<CL_XMLTokenString, CL_XMLTokenString> const & attribute = cur_token.get_attribute_fast(i);
					element.set_attribute(attribute.first.to_string(), attribute.second.to_string());
				}
				
				if (cur_token.get_variant() == CL_XMLToken::BEGIN)
					node_stack.push(element);
			}
			else
			{
				node_stack.pop();
				if (node_stack.empty()) throw CL_Error("Malformed XML tree!");
			}
			break;

		case CL_XMLToken::NULL_TOKEN: 
			break;

		case CL_XMLToken::ENTITY_REFERENCE_TOKEN: 
			break;

		case CL_XMLToken::ENTITY_TOKEN: 
			break;
			
		case CL_XMLToken::COMMENT_TOKEN:
			break;

		case CL_XMLToken::DOCUMENT_TYPE_TOKEN:
			break;

		case CL_XMLToken::NOTATION_TOKEN:
			break;

		case CL_XMLToken::PROCESSING_INSTRUCTION_TOKEN:
			break;
		}		

		cur_token = tokenizer.next();
	}
}

void CL_DomDocument::save(CL_OutputSource *output, bool delete_output, bool insert_whitespace)
{
	CL_XMLWriter writer(output, delete_output);
	writer.set_insert_whitespace(insert_whitespace);

	std::stack<CL_DomNode> node_stack;
	CL_DomNode cur_node = get_first_child();
	while (!cur_node.is_null())
	{
		// Create opening node:
		CL_XMLTokenSave opening_node;
		opening_node.set_type((CL_XMLToken::TokenType) cur_node.get_node_type());
		opening_node.set_variant(cur_node.has_child_nodes() ? CL_XMLToken::BEGIN : CL_XMLToken::SINGLE);
		opening_node.set_name(cur_node.get_node_name());
		opening_node.set_value(cur_node.get_node_value());
		if (cur_node.is_element())
		{
			std::vector<std::pair<std::string, CL_DomNode_Generic *> >::iterator it;
			for (it = cur_node.impl->attributes.begin(); it != cur_node.impl->attributes.end(); ++it)
			{
				opening_node.set_attribute(it->first, it->second->node_value);
			}
		}
		writer.write(opening_node);

		// Create any possible child nodes:
		if (cur_node.has_child_nodes())
		{
			node_stack.push(cur_node);
			cur_node = cur_node.get_first_child();
			continue;
		}

		// Create closing nodes until we reach next opening node in tree:
		while (true)
		{
			if (cur_node.has_child_nodes())
			{
				CL_XMLTokenSave closing_node;
				closing_node.set_type((CL_XMLToken::TokenType) cur_node.get_node_type());
				closing_node.set_name(cur_node.get_node_name());
				closing_node.set_variant(CL_XMLToken::END);
				writer.write(closing_node);
			}

			cur_node = cur_node.get_next_sibling();
			if (!cur_node.is_null()) break;
			if (node_stack.empty()) break;

			cur_node = node_stack.top();
			node_stack.pop();
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CL_DomDocument implementation:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -