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

📄 xmlstorage.h

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 H
📖 第 1 页 / 共 4 页
字号:
	std::string	_href;		// CDATA #REQUIRED
	std::string	_type;		// CDATA #REQUIRED
	std::string	_title;		// CDATA #IMPLIED
	std::string	_media;		// CDATA #IMPLIED
	std::string	_charset;	// CDATA #IMPLIED
	bool		_alternate;	// (yes|no) "no"

	StyleSheet() : _alternate(false) {}

	StyleSheet(const std::string& href, const std::string& type="text/xsl", bool alternate=false)
	 :	_href(href),
		_type(type),
		_alternate(alternate)
	{
	}

	bool empty() const {return _href.empty();}
	void print(std::ostream& out) const;
};

 /// list of StyleSheet entries
struct StyleSheetList : public std::list<StyleSheet>
{
	void set(const StyleSheet& stylesheet)
	{
		clear();
		push_back(stylesheet);
	}
};


 /// XML document type description
struct DocType
{
	std::string	_name;

	 // External Document Types are noted, but not parsed.
	std::string	_public;
	std::string	_system;

	 // Internal DTDs are not supported.

	void parse(const char* str);
	bool empty() const {return _name.empty();}
};

 /// Management of XML file headers and formating
struct XMLFormat
{
	XMLFormat(PRETTY_FLAGS pretty=PRETTY_INDENT, const std::string& xml_version="1.0", const std::string& encoding="utf-8", const DocType& doctype=DocType())
	 :	_pretty(pretty),
		_endl("\n"),
		_version(xml_version),
		_encoding(encoding),
		_doctype(doctype),
		_standalone(-1)
	{
	}

	void print_header(std::ostream& out, bool lf=true) const;

	PRETTY_FLAGS _pretty;
	const char*	_endl;		// line ending string: "\n" or "\r\n"

	std::string _version;
	std::string _encoding;

	DocType		_doctype;

	StyleSheetList _stylesheets;

//	std::string _additional;

	int		_standalone;
};


enum WRITE_MODE {
	FORMAT_PLAIN,		/// write XML without any white space
	FORMAT_SMART,		/// preserve original white space and comments if present; pretty print otherwise
	FORMAT_ORIGINAL,	/// write XML stream preserving original white space and comments
	FORMAT_PRETTY 		/// pretty print node to stream without preserving original white space
};


 /// in memory representation of an XML node
struct XMLNode : public XS_String
{
#if defined(UNICODE) && !defined(XS_STRING_UTF8)
	 /// map of XML node attributes
	 // optimized read access without temporary A/U conversion when using ASCII attribute names
	struct AttributeMap : public std::map<XS_String, XS_String>
	{
		typedef std::map<XS_String, XS_String> super;

		const_iterator find(const char* x) const
		{
			for(const_iterator it=begin(); it!=end(); ++it)
				if (it->first == x)
					return it;

			return end();
		}

		const_iterator find(const key_type& x) const
		{
			return super::find(x);
		}

		iterator find(const key_type& x)
		{
			return super::find(x);
		}

		XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
		{
			const_iterator found = find(x);

			if (found != end())
				return found->second;
			else
				return def;
		}
	};
#else
	 /// map of XML node attributes
	struct AttributeMap : public std::map<XS_String, XS_String>
	{
		XS_String get(const char* x, LPCXSSTR def=XS_EMPTY_STR) const
		{
			const_iterator found = find(x);

			if (found != end())
				return found->second;
			else
				return def;
		}
	};
#endif

	 /// internal children node list
	struct Children : public std::list<XMLNode*>
	{
		void assign(const Children& other)
		{
			clear();

			for(Children::const_iterator it=other.begin(); it!=other.end(); ++it)
				push_back(new XMLNode(**it));
		}

		void clear()
		{
			while(!empty()) {
				XMLNode* node = back();
				pop_back();

				node->clear();
				delete node;
			}
		}
	};

	 // access to protected class members for XMLPos and XMLReader
	friend struct XMLPos;
	friend struct const_XMLPos;
	friend struct XMLReaderBase;

	XMLNode(const XS_String& name)
	 :	XS_String(name)
	{
	}

	XMLNode(const XS_String& name, const std::string& leading)
	 :	XS_String(name),
		_leading(leading)
	{
	}

	XMLNode(const XMLNode& other)
	 :	XS_String(other),
		_attributes(other._attributes),
		_leading(other._leading),
		_content(other._content),
		_end_leading(other._end_leading),
		_trailing(other._trailing)
#ifdef XMLNODE_LOCATION
		, _location(other._location)
#endif
	{
		for(Children::const_iterator it=other._children.begin(); it!=other._children.end(); ++it)
			_children.push_back(new XMLNode(**it));
	}

	virtual ~XMLNode()
	{
		while(!_children.empty()) {
			delete _children.back();
			_children.pop_back();
		}
	}

	void clear()
	{
		_leading.erase();
		_content.erase();
		_end_leading.erase();
		_trailing.erase();

		_attributes.clear();
		_children.clear();

		XS_String::erase();
	}

	XMLNode& operator=(const XMLNode& other)
	{
		_children.assign(other._children);

		_attributes = other._attributes;

		_leading = other._leading;
		_content = other._content;
		_end_leading = other._end_leading;
		_trailing = other._trailing;

		return *this;
	}

	 /// add a new child node
	void add_child(XMLNode* child)
	{
		_children.push_back(child);
	}

	 /// write access to an attribute
	void put(const XS_String& attr_name, const XS_String& value)
	{
		_attributes[attr_name] = value;
	}

	 /// C++ write access to an attribute
	XS_String& operator[](const XS_String& attr_name)
	{
		return _attributes[attr_name];
	}

	 /// read only access to an attribute
	template<typename T> XS_String get(const T& attr_name, LPCXSSTR def=XS_EMPTY_STR) const
	{
		AttributeMap::const_iterator found = _attributes.find(attr_name);

		if (found != _attributes.end())
			return found->second;
		else
			return def;
	}

	 /// convenient value access in children node
	XS_String subvalue(const XS_String& name, const XS_String& attr_name, int n=0) const
	{
		const XMLNode* node = find(name, n);

		if (node)
			return node->get(attr_name);
		else
			return XS_String();
	}

	 /// convenient storage of distinct values in children node
	XS_String& subvalue(const XS_String& name, const XS_String& attr_name, int n=0)
	{
		XMLNode* node = find(name, n);

		if (!node) {
			node = new XMLNode(name);
			add_child(node);
		}

		return (*node)[attr_name];
	}

#if defined(UNICODE) && !defined(XS_STRING_UTF8)
	 /// convenient value access in children node
	XS_String subvalue(const char* name, const char* attr_name, int n=0) const
	{
		const XMLNode* node = find(name, n);

		if (node)
			return node->get(attr_name);
		else
			return XS_String();
	}

	 /// convenient storage of distinct values in children node
	XS_String& subvalue(const char* name, const XS_String& attr_name, int n=0)
	{
		XMLNode* node = find(name, n);

		if (!node) {
			node = new XMLNode(name);
			add_child(node);
		}

		return (*node)[attr_name];
	}
#endif

	const Children& get_children() const
	{
		return _children;
	}

	Children& get_children()
	{
		return _children;
	}

	const AttributeMap& get_attributes() const
	{
		return _attributes;
	}

	AttributeMap& get_attributes()
	{
		return _attributes;
	}

	XS_String get_content() const
	{
#ifdef XS_STRING_UTF8
		const XS_String& ret = _content;
#else
		XS_String ret;
		assign_utf8(ret, _content.c_str(), _content.length());
#endif

		return DecodeXMLString(ret.c_str());
	}

	void set_content(const XS_String& s, bool cdata=false)
	{
		_content.assign(EncodeXMLString(s.c_str(), cdata));
	}

#ifdef XMLNODE_LOCATION
	const XMLLocation& get_location() const {return _location;}
#endif

	 /// write node with children tree to output stream
	bool write(std::ostream& out, const XMLFormat& format, WRITE_MODE mode=FORMAT_SMART, int indent=0) const
	{
		switch(mode) {
		  case FORMAT_PLAIN:
			plain_write_worker(out);
			break;

		  case FORMAT_PRETTY:
			pretty_write_worker(out, format, indent);
			break;

		  case FORMAT_ORIGINAL:
			write_worker(out, indent);
			break;

		default:	 // FORMAT_SMART
			smart_write_worker(out, format, indent);
		}

		return out.good();
	}

protected:
	Children _children;
	AttributeMap _attributes;

	std::string _leading;		// UTF-8 encoded
	std::string _content;		// UTF-8 and entity encoded, may contain CDATA sections; decode with DecodeXMLString()
	std::string _end_leading;	// UTF-8 encoded
	std::string _trailing;		// UTF-8 encoded

#ifdef XMLNODE_LOCATION
	XMLLocation	_location;
#endif

	XMLNode* get_first_child() const
	{
		if (!_children.empty())
			return _children.front();
		else
			return NULL;
	}

	XMLNode* find(const XS_String& name, int n=0) const
	{
		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
			if (**it == name)
				if (!n--)
					return *it;

		return NULL;
	}

	XMLNode* find(const XS_String& name, const XS_String& attr_name, const XS_String& attr_value, int n=0) const
	{
		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
			const XMLNode& node = **it;

			if (node==name && node.get(attr_name)==attr_value)
				if (!n--)
					return *it;
		}

		return NULL;
	}

#if defined(UNICODE) && !defined(XS_STRING_UTF8)
	XMLNode* find(const char* name, int n=0) const
	{
		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it)
			if (**it == name)
				if (!n--)
					return *it;

		return NULL;
	}

	template<typename T, typename U>
	XMLNode* find(const char* name, const T& attr_name, const U& attr_value, int n=0) const
	{
		for(Children::const_iterator it=_children.begin(); it!=_children.end(); ++it) {
			const XMLNode& node = **it;

			if (node==name && node.get(attr_name)==attr_value)
				if (!n--)
					return *it;
		}

		return NULL;
	}
#endif

	 /// XPath find function (const)
	const XMLNode* find_relative(const char* path) const;

	 /// XPath find function
	XMLNode* find_relative(const char* path)
		{return const_cast<XMLNode*>(const_cast<const XMLNode*>(this)->find_relative(path));}

	 /// relative XPath create function
	XMLNode* create_relative(const char* path);

	void	write_worker(std::ostream& out, int indent) const;
	void	plain_write_worker(std::ostream& out) const;
	void	pretty_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
	void	smart_write_worker(std::ostream& out, const XMLFormat& format, int indent) const;
};


 /// iterator access to children nodes with name filtering
struct XMLChildrenFilter
{
	XMLChildrenFilter(XMLNode::Children& children, const XS_String& name)
	 :	_begin(children.begin(), children.end(), name),
		_end(children.end(), children.end(), name)
	{
	}

	XMLChildrenFilter(XMLNode* node, const XS_String& name)
	 :	_begin(node->get_children().begin(), node->get_children().end(), name),
		_end(node->get_children().end(), node->get_children().end(), name)
	{
	}

	 /// internal iterator class
	struct iterator
	{
		typedef XMLNode::Children::iterator BaseIterator;

		iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name)
		 :	_cur(begin),
			_end(end),
			_filter_name(filter_name)
		{
			search_next();
		}

		operator BaseIterator()
		{
			return _cur;
		}

		const XMLNode* operator*() const
		{
			return *_cur;
		}

		XMLNode* operator*()
		{
			return *_cur;
		}

		iterator& operator++()
		{
			++_cur;
			search_next();

			return *this;
		}

		iterator operator++(int)
		{
			iterator ret = *this;

			++_cur;
			search_next();

			return ret;
		}

		bool operator==(const BaseIterator& other) const
		{
			return _cur == other;
		}

		bool operator!=(const BaseIterator& other) const
		{
			return _cur != other;
		}

	protected:
		BaseIterator	_cur;
		BaseIterator	_end;
		XS_String	_filter_name;

		void search_next()
		{
			while(_cur!=_end && **_cur!=_filter_name)
				++_cur;
		}
	};

	iterator begin()
	{
		return _begin;
	}

	iterator end()
	{
		return _end;
	}

protected:
	iterator	_begin;
	iterator	_end;
};


 /// read only iterator access to children nodes with name filtering
struct const_XMLChildrenFilter
{
	const_XMLChildrenFilter(const XMLNode::Children& children, const XS_String& name)
	 :	_begin(children.begin(), children.end(), name),
		_end(children.end(), children.end(), name)
	{
	}

	const_XMLChildrenFilter(const XMLNode* node, const XS_String& name)
	 :	_begin(node->get_children().begin(), node->get_children().end(), name),
		_end(node->get_children().end(), node->get_children().end(), name)
	{
	}

	 /// internal iterator class
	struct const_iterator
	{
		typedef XMLNode::Children::const_iterator BaseIterator;

		const_iterator(BaseIterator begin, BaseIterator end, const XS_String& filter_name)
		 :	_cur(begin),
			_end(end),
			_filter_name(filter_name)
		{
			search_next();
		}

		operator BaseIterator()
		{
			return _cur;
		}

		const XMLNode* operator*() const
		{
			return *_cur;
		}

		const_iterator& operator++()
		{
			++_cur;
			search_next();

			return *this;
		}

		const_iterator operator++(int)
		{
			const_iterator ret = *this;

			++_cur;
			search_next();

			return ret;
		}

		bool operator==(const BaseIterator& other) const
		{
			return _cur == other;
		}

		bool operator!=(const BaseIterator& other) const
		{
			return _cur != other;
		}

	protected:
		BaseIterator	_cur;
		BaseIterator	_end;
		XS_String	_filter_name;

		void search_next()
		{
			while(_cur!=_end && **_cur!=_filter_name)
				++_cur;
		}
	};

	const_iterator begin()
	{
		return _begin;
	}

	const_iterator end()
	{
		return _end;
	}

protected:
	const_iterator	_begin;
	const_iterator	_end;
};


 /// iterator for XML trees
struct XMLPos
{
	XMLPos(XMLNode* root)
	 :	_root(root),
		_cur(root)
	{
	}

	XMLPos(const XMLPos& other)
	 :	_root(other._root),

⌨️ 快捷键说明

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