欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

xmlstorage.cpp

一个类似windows
CPP
第 1 页 / 共 2 页
字号:

	for(; p<e; ++p)
		if (*p == '\n') {
			++p;
			break;
		}

	if (p != s)
		if (pos->_children.empty()) {	// no children in last node?
			if (pReader->_last_tag == TAG_START)
				pos->_content.append(s, p-s);
			else if (pReader->_last_tag == TAG_END)
				pos->_trailing.append(s, p-s);
			// else TAG_NONE -> don't store white space in root node
		} else
			pos->_children.back()->_trailing.append(s, p-s);

	std::string leading;

	if (p != e)
		leading.assign(p, e-p);

	XMLNode* node = new XMLNode(String_from_XML_Char(name), leading);

	pos.add_down(node);

	while(*atts) {
		const XML_Char* attr_name = *atts++;
		const XML_Char* attr_value = *atts++;

		(*node)[String_from_XML_Char(attr_name)] = String_from_XML_Char(attr_value);
	}

	pReader->_last_tag = TAG_START;
	pReader->_content.erase();
}

 /// notifications about XML end tag
void XMLCALL XMLReaderBase::XML_EndElementHandler(void* userData, const XML_Char* name)
{
	XMLReaderBase* pReader = (XMLReaderBase*) userData;
	XMLPos& pos = pReader->_pos;

	 // search for end of first line
	const char* s = pReader->_content.c_str();
	const char* p = s;
	const char* e = p + pReader->_content.length();

	for(; p<e; ++p)
		if (*p == '\n') {
			++p;
			break;
		}

	if (p != s)
		if (pos->_children.empty())	// no children in current node?
			pos->_content.append(s, p-s);
		else
			if (pReader->_last_tag == TAG_START)
				pos->_content.append(s, p-s);
			else
				pos->_children.back()->_trailing.append(s, p-s);

	if (p != e)
		pos->_end_leading.assign(p, e-p);

	pos.back();

	pReader->_last_tag = TAG_END;
	pReader->_content.erase();
}

 /// store content, white space and comments
void XMLCALL XMLReaderBase::XML_DefaultHandler(void* userData, const XML_Char* s, int len)
{
	XMLReaderBase* pReader = (XMLReaderBase*) userData;

	pReader->_content.append(s, len);
}


std::string XMLReaderBase::get_error_string() const
{
	XML_Error error = XML_GetErrorCode(_parser);

	switch(error) {
	  case XML_ERROR_NONE:								return "XML_ERROR_NONE";
	  case XML_ERROR_NO_MEMORY:							return "XML_ERROR_NO_MEMORY";
	  case XML_ERROR_SYNTAX:							return "XML_ERROR_SYNTAX";
	  case XML_ERROR_NO_ELEMENTS:						return "XML_ERROR_NO_ELEMENTS";
	  case XML_ERROR_INVALID_TOKEN:						return "XML_ERROR_INVALID_TOKEN";
	  case XML_ERROR_UNCLOSED_TOKEN:					return "XML_ERROR_UNCLOSED_TOKEN";
	  case XML_ERROR_PARTIAL_CHAR:						return "XML_ERROR_PARTIAL_CHAR";
	  case XML_ERROR_TAG_MISMATCH:						return "XML_ERROR_TAG_MISMATCH";
	  case XML_ERROR_DUPLICATE_ATTRIBUTE:				return "XML_ERROR_DUPLICATE_ATTRIBUTE";
	  case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:			return "XML_ERROR_JUNK_AFTER_DOC_ELEMENT";
	  case XML_ERROR_PARAM_ENTITY_REF:					return "XML_ERROR_PARAM_ENTITY_REF";
	  case XML_ERROR_UNDEFINED_ENTITY:					return "XML_ERROR_UNDEFINED_ENTITY";
	  case XML_ERROR_RECURSIVE_ENTITY_REF:				return "XML_ERROR_RECURSIVE_ENTITY_REF";
	  case XML_ERROR_ASYNC_ENTITY:						return "XML_ERROR_ASYNC_ENTITY";
	  case XML_ERROR_BAD_CHAR_REF:						return "XML_ERROR_BAD_CHAR_REF";
	  case XML_ERROR_BINARY_ENTITY_REF:					return "XML_ERROR_BINARY_ENTITY_REF";
	  case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:		return "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF";
	  case XML_ERROR_MISPLACED_XML_PI:					return "XML_ERROR_MISPLACED_XML_PI";
	  case XML_ERROR_UNKNOWN_ENCODING:					return "XML_ERROR_UNKNOWN_ENCODING";
	  case XML_ERROR_INCORRECT_ENCODING:				return "XML_ERROR_INCORRECT_ENCODING";
	  case XML_ERROR_UNCLOSED_CDATA_SECTION:			return "XML_ERROR_UNCLOSED_CDATA_SECTION";
	  case XML_ERROR_EXTERNAL_ENTITY_HANDLING:			return "XML_ERROR_EXTERNAL_ENTITY_HANDLING";
	  case XML_ERROR_NOT_STANDALONE:					return "XML_ERROR_NOT_STANDALONE";
	  case XML_ERROR_UNEXPECTED_STATE:					return "XML_ERROR_UNEXPECTED_STATE";
	  case XML_ERROR_ENTITY_DECLARED_IN_PE:				return "XML_ERROR_ENTITY_DECLARED_IN_PE";
	  case XML_ERROR_FEATURE_REQUIRES_XML_DTD:			return "XML_ERROR_FEATURE_REQUIRES_XML_DTD";
	  case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:	return "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING";
	  case XML_ERROR_UNBOUND_PREFIX:					return "XML_ERROR_UNBOUND_PREFIX";
 // EXPAT version >= 1.95.8
#if XML_MAJOR_VERSION>1 || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION>95) || (XML_MAJOR_VERSION==1 && XML_MINOR_VERSION==95 && XML_MICRO_VERSION>7)
	  case XML_ERROR_UNDECLARING_PREFIX:				return "XML_ERROR_UNDECLARING_PREFIX";
	  case XML_ERROR_INCOMPLETE_PE:						return "XML_ERROR_INCOMPLETE_PE";
	  case XML_ERROR_XML_DECL:							return "XML_ERROR_XML_DECL";
	  case XML_ERROR_TEXT_DECL:							return "XML_ERROR_TEXT_DECL";
	  case XML_ERROR_PUBLICID:							return "XML_ERROR_PUBLICID";
	  case XML_ERROR_SUSPENDED:							return "XML_ERROR_SUSPENDED";
	  case XML_ERROR_NOT_SUSPENDED:						return "XML_ERROR_NOT_SUSPENDED";
	  case XML_ERROR_ABORTED:							return "XML_ERROR_ABORTED";
	  case XML_ERROR_FINISHED:							return "XML_ERROR_FINISHED";
	  case XML_ERROR_SUSPEND_PE:						return "XML_ERROR_SUSPEND_PE";
//#endif
//#if XML_MAJOR_VERSION>=2
		/* Added in 2.0. */
	  case XML_ERROR_RESERVED_PREFIX_XML:				return "XML_ERROR_RESERVED_PREFIX_XML";
	  case XML_ERROR_RESERVED_PREFIX_XMLNS:				return "XML_ERROR_RESERVED_PREFIX_XMLNS";
	  case XML_ERROR_RESERVED_NAMESPACE_URI:			return "XML_ERROR_RESERVED_NAMESPACE_URI";
#endif
	}

	std::ostringstream out;

	out << "XML parser error #" << error;

	return out.str();
}


std::string EncodeXMLString(const XS_String& str)
{
	LPCXSSTR s = str.c_str();
	LPXSSTR buffer = (LPXSSTR)alloca(5*sizeof(XS_CHAR)*XS_len(s));	// worst case. "&amp;"
	LPXSSTR o = buffer;

	for(LPCXSSTR p=s; *p; ++p)
		switch(*p) {
		  case '&':
			*o++ = '&';	*o++ = 'a';	*o++ = 'm';	*o++ = 'p';	*o++ = ';';
			break;

		  case '<':
			*o++ = '&';	*o++ = 'l'; *o++ = 't';	*o++ = ';';
			break;

		  case '>':
			*o++ = '&';	*o++ = 'g'; *o++ = 't';	*o++ = ';';
			break;

		  case '"':
			*o++ = '&';	*o++ = 'q'; *o++ = 'u'; *o++ = 'o'; *o++ = 't';	*o++ = ';';
			break;

		  case '\'':
			*o++ = '&';	*o++ = 'a'; *o++ = 'p'; *o++ = 'o'; *o++ = 's';	*o++ = ';';
			break;

		  default:
			*o++ = *p;
		}

#ifdef XS_STRING_UTF8
	return XS_String(buffer, o-buffer);
#else
	return get_utf8(buffer, o-buffer);
#endif
}

XS_String DecodeXMLString(const XS_String& str)
{
	LPCXSSTR s = str.c_str();
	LPXSSTR buffer = (LPXSSTR)alloca(sizeof(XS_CHAR)*XS_len(s));
	LPXSSTR o = buffer;

	for(LPCXSSTR p=s; *p; ++p)
		if (*p == '&') {
			if (!XS_nicmp(p+1, XS_TEXT("lt;"), 3)) {
				*o++ = '<';
				p += 3;
			} else if (!XS_nicmp(p+1, XS_TEXT("gt;"), 3)) {
				*o++ = '>';
				p += 3;
			} else if (!XS_nicmp(p+1, XS_TEXT("amp;"), 4)) {
				*o++ = '&';
				p += 4;
			} else if (!XS_nicmp(p+1, XS_TEXT("quot;"), 5)) {
				*o++ = '"';
				p += 5;
			} else if (!XS_nicmp(p+1, XS_TEXT("apos;"), 5)) {
				*o++ = '\'';
				p += 5;
			} else
				*o++ = *p;
		} else
			*o++ = *p;

	return XS_String(buffer, o-buffer);
}


 /// write node with children tree to output stream using original white space
void XMLNode::write_worker(std::ostream& out, int indent) const
{
	out << _leading << '<' << EncodeXMLString(*this);

	for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
		out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";

	if (!_children.empty() || !_content.empty()) {
		out << '>' << _content;

		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
			(*it)->write_worker(out, indent+1);

		out << _end_leading << "</" << EncodeXMLString(*this) << '>';
	} else
		out << "/>";

	out << _trailing;
}


 /// pretty print node with children tree to output stream
void XMLNode::pretty_write_worker(std::ostream& out, int indent) const
{
	for(int i=indent; i--; )
		out << XML_INDENT_SPACE;

	out << '<' << EncodeXMLString(*this);

	for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
		out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";

	if (!_children.empty() || !_content.empty()) {
		out << ">\n";

		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
			(*it)->pretty_write_worker(out, indent+1);

		for(int i=indent; i--; )
			out << XML_INDENT_SPACE;

		out << "</" << EncodeXMLString(*this) << ">\n";
	} else
		out << "/>\n";
}


 /// write node with children tree to output stream using smart formating
void XMLNode::smart_write_worker(std::ostream& out, int indent) const
{
	if (_leading.empty())
		for(int i=indent; i--; )
			out << XML_INDENT_SPACE;
	else
		out << _leading;

	out << '<' << EncodeXMLString(*this);

	for(AttributeMap::const_iterator it=_attributes.begin(); it!=_attributes.end(); ++it)
		out << ' ' << EncodeXMLString(it->first) << "=\"" << EncodeXMLString(it->second) << "\"";

	if (_children.empty() && _content.empty())
		out << "/>";
	else {
		out << '>';

		if (_content.empty())
			out << '\n';
		else
			out << _content;

		Children::const_iterator it = _children.begin();

		if (it != _children.end()) {
			for(; it!=_children.end(); ++it)
				(*it)->smart_write_worker(out, indent+1);

			if (_end_leading.empty())
				for(int i=indent; i--; )
					out << XML_INDENT_SPACE;
			else
				out << _end_leading;
		} else
			out << _end_leading;

		out << "</" << EncodeXMLString(*this) << '>';
	}

	if (_trailing.empty())
		out << '\n';
	else
		out << _trailing;
}


}	// namespace XMLStorage

⌨️ 快捷键说明

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