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

📄 xmlwriter.cpp.svn-base

📁 很好用的网络封装库,不熟悉网络编程的人也可以使用。使用风格良好的标准c++编写。
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
//
// XMLWriter.cpp
//
// $Id: //poco/1.3/XML/src/XMLWriter.cpp#2 $
//
// Library: XML
// Package: XML
// Module:  XMLWriter
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
// 
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//


#include "Poco/XML/XMLWriter.h"
#include "Poco/XML/XMLString.h"
#include "Poco/XML/XMLException.h"
#include "Poco/SAX/AttributesImpl.h"
#include "Poco/UTF8Encoding.h"
#include "Poco/UTF16Encoding.h"
#include <sstream>


namespace Poco {
namespace XML {


const std::string XMLWriter::NEWLINE_DEFAULT;
const std::string XMLWriter::NEWLINE_CR         = "\r";
const std::string XMLWriter::NEWLINE_CRLF       = "\r\n";
const std::string XMLWriter::NEWLINE_LF         = "\n";
const std::string XMLWriter::MARKUP_QUOTENC     = "&quot;";
const std::string XMLWriter::MARKUP_APOSENC     = "&apos;";
const std::string XMLWriter::MARKUP_AMPENC      = "&amp;";
const std::string XMLWriter::MARKUP_LTENC       = "&lt;";
const std::string XMLWriter::MARKUP_GTENC       = "&gt;";
const std::string XMLWriter::MARKUP_LT          = "<";
const std::string XMLWriter::MARKUP_GT          = ">";
const std::string XMLWriter::MARKUP_SLASHGT     = "/>";
const std::string XMLWriter::MARKUP_LTSLASH     = "</";
const std::string XMLWriter::MARKUP_COLON       = ":";
const std::string XMLWriter::MARKUP_EQQUOT      = "=\"";
const std::string XMLWriter::MARKUP_QUOT        = "\"";
const std::string XMLWriter::MARKUP_SPACE       = " ";
const std::string XMLWriter::MARKUP_TAB         = "\t";
const std::string XMLWriter::MARKUP_BEGIN_CDATA = "<![CDATA[";
const std::string XMLWriter::MARKUP_END_CDATA   = "]]>";


#if defined(XML_UNICODE_WCHAR_T)
	#define NATIVE_ENCODING Poco::UTF16Encoding
#else
	#define NATIVE_ENCODING Poco::UTF8Encoding
#endif


XMLWriter::XMLWriter(XMLByteOutputStream& str, int options):
	_pTextConverter(0),
	_pInEncoding(new NATIVE_ENCODING),
	_pOutEncoding(new Poco::UTF8Encoding),
	_options(options),
	_encoding("UTF-8"),
	_depth(-1),
	_elementCount(0),
	_inFragment(false),
	_inCDATA(false),
	_inDTD(false),
	_inInternalDTD(false),
	_contentWritten(false),
	_unclosedStartTag(false),
	_prefix(0)
{
	_pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *_pOutEncoding);
	setNewLine(NEWLINE_DEFAULT);
}


XMLWriter::XMLWriter(XMLByteOutputStream& str, int options, const std::string& encodingName, Poco::TextEncoding& textEncoding):
	_pTextConverter(0),
	_pInEncoding(new NATIVE_ENCODING),
	_pOutEncoding(0),
	_options(options),
	_encoding(encodingName),
	_depth(-1),
	_elementCount(0),
	_inFragment(false),
	_inCDATA(false),
	_inDTD(false),
	_inInternalDTD(false),
	_contentWritten(false),
	_unclosedStartTag(false),
	_prefix(0)
{
	_pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, textEncoding);
	setNewLine(NEWLINE_DEFAULT);
}


XMLWriter::XMLWriter(XMLByteOutputStream& str, int options, const std::string& encodingName, Poco::TextEncoding* pTextEncoding):
	_pTextConverter(0),
	_pInEncoding(new NATIVE_ENCODING),
	_pOutEncoding(0),
	_options(options),
	_encoding(encodingName),
	_depth(-1),
	_elementCount(0),
	_inFragment(false),
	_inCDATA(false),
	_inDTD(false),
	_inInternalDTD(false),
	_contentWritten(false),
	_unclosedStartTag(false),
	_prefix(0)
{
	if (pTextEncoding)
	{
		_pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *pTextEncoding);
	}
	else
	{
		_encoding = "UTF-8";
		_pOutEncoding = new Poco::UTF8Encoding;
		_pTextConverter = new Poco::OutputStreamConverter(str, *_pInEncoding, *_pOutEncoding);
	}
	setNewLine(NEWLINE_DEFAULT);
}


XMLWriter::~XMLWriter()
{
	delete _pTextConverter;
	delete _pInEncoding;
	delete _pOutEncoding;
}


void XMLWriter::setDocumentLocator(const Locator* loc)
{
}


void XMLWriter::setNewLine(const std::string& newLineCharacters)
{
	if (newLineCharacters.empty())
	{
#if defined(_WIN32)
		_newLine = NEWLINE_CRLF;
#else
		_newLine = NEWLINE_LF;
#endif
	}
	else _newLine = newLineCharacters;
}


const std::string& XMLWriter::getNewLine() const
{
	return _newLine;
}


void XMLWriter::startDocument()
{
	if (_depth != -1)
		throw XMLException("Cannot start a document in another document");

	_inFragment    = false;
	_depth         = 0;
	_elementCount  = 0;
	_inDTD         = false;
	_inInternalDTD = false;
	_prefix        = 0;

	if (_options & WRITE_XML_DECLARATION)
		writeXMLDeclaration();
	
	_contentWritten = true;
	_namespaces.reset();
	_namespaces.pushContext();
}


void XMLWriter::endDocument()
{
	if (_depth > 0)
		throw XMLException("Not well-formed (at least one tag has no matching end tag)");
	if (_elementCount == 0)
		throw XMLException("No document element");

	poco_assert_dbg (!_unclosedStartTag);

	_elementCount = 0;
	_depth        = -1;
}


void XMLWriter::startFragment()
{
	if (_depth != -1)
		throw XMLException("Cannot start a fragment in another fragment or document");

	_inFragment   = true;
	_depth        = 0;
	_elementCount = 0;
	_prefix       = 0;

	_contentWritten = true;
	_namespaces.reset();
	_namespaces.pushContext();
}


void XMLWriter::endFragment()
{
	if (_depth > 1)
		throw XMLException("Not well-formed (at least one tag has no matching end tag)");
	
	_inFragment   = false;
	_elementCount = 0;
	_depth        = -1;
}


void XMLWriter::startElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname)
{
	static const AttributesImpl attributes;
	startElement(namespaceURI, localName, qname, attributes);
}


void XMLWriter::startElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes)
{
	if (_depth == 0 && !_inFragment && _elementCount > 1) 
		throw XMLException("Not well-formed. Second root element found", nameToString(localName, qname));
	
	if (_unclosedStartTag) closeStartTag();
	prettyPrint();
	writeStartElement(namespaceURI, localName, qname, attributes);
	_elementStack.push_back(Name(qname, namespaceURI, localName));
	_contentWritten = false;
	++_depth;
}


void XMLWriter::endElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname)
{
	if (_depth < 1)
		throw XMLException("No unclosed tag");

	if (!_elementStack.back().equalsWeakly(qname, namespaceURI, localName))
		throw XMLException("End tag does not match start tag", nameToString(localName, qname));

	_elementStack.pop_back();
	--_depth;
	if (!_unclosedStartTag) prettyPrint();
	writeEndElement(namespaceURI, localName, qname);
	_contentWritten = false;
	if (_depth == 0)
		writeNewLine();
}


void XMLWriter::emptyElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname)
{
	static const AttributesImpl attributes;
	emptyElement(namespaceURI, localName, qname, attributes);
}


void XMLWriter::emptyElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname, const Attributes& attributes)
{
	if (_depth == 0 && _elementCount > 1)
		throw XMLException("Not well-formed. Second root element found.");

	if (_unclosedStartTag) closeStartTag();
	prettyPrint();
	writeStartElement(namespaceURI, localName, qname, attributes);
	_contentWritten = false;
	writeMarkup("/");
	closeStartTag();
}


void XMLWriter::characters(const XMLChar ch[], int start, int length)
{
	if (length == 0) return;

	if (_unclosedStartTag) closeStartTag();
	_contentWritten = _contentWritten || length > 0;
	if (_inCDATA)
	{
		while (length-- > 0) writeXML(ch[start++]);
	}
	else
	{
		while (length-- > 0)
		{
			XMLChar c = ch[start++];
			switch (c)
			{
			case '"':  writeMarkup(MARKUP_QUOTENC); break;
			case '\'': writeMarkup(MARKUP_APOSENC); break;
			case '&':  writeMarkup(MARKUP_AMPENC); break;
			case '<':  writeMarkup(MARKUP_LTENC); break;
			case '>':  writeMarkup(MARKUP_GTENC); break;
			default:
				if (c >= 0 && c < 32)
				{
					if (c == '\t' || c == '\r' || c == '\n')
						writeXML(c);
					else
						throw XMLException("Invalid character token.");
				}
				else writeXML(c);
			}
		}
	}
}


void XMLWriter::characters(const XMLString& str)
{
	characters(str.data(), 0, (int) str.length());
}


void XMLWriter::rawCharacters(const XMLString& str)
{
	if (_unclosedStartTag) closeStartTag();
	_contentWritten = _contentWritten || !str.empty();
	writeXML(str);
}


void XMLWriter::ignorableWhitespace(const XMLChar ch[], int start, int length)
{
	characters(ch, start, length);
}


void XMLWriter::processingInstruction(const XMLString& target, const XMLString& data)
{
	if (_unclosedStartTag) closeStartTag();
	prettyPrint();
	writeMarkup("<?");
	writeXML(target);
	if (!data.empty())
	{
		writeMarkup(MARKUP_SPACE);
		writeXML(data);
	}
	writeMarkup("?>");
	if (_depth == 0)
		writeNewLine();
}


void XMLWriter::dataElement(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname,
                             const XMLString& data,
	                         const XMLString& attr1, const XMLString& value1,
							 const XMLString& attr2, const XMLString& value2,
							 const XMLString& attr3, const XMLString& value3)
{
	static const XMLString CDATA = toXMLString("CDATA");

	AttributesImpl attributes;
	if (!attr1.empty()) attributes.addAttribute(XMLString(), XMLString(), attr1, CDATA, value1);
	if (!attr2.empty()) attributes.addAttribute(XMLString(), XMLString(), attr2, CDATA, value2);
	if (!attr3.empty()) attributes.addAttribute(XMLString(), XMLString(), attr3, CDATA, value3);
	if (data.empty())
	{
		emptyElement(namespaceURI, localName, qname, attributes);
	}
	else
	{
		startElement(namespaceURI, localName, qname, attributes);
		characters(data);
		endElement(namespaceURI, localName, qname);
	}
}


void XMLWriter::startPrefixMapping(const XMLString& prefix, const XMLString& namespaceURI)
{
	if (prefix != NamespaceSupport::XML_NAMESPACE_PREFIX)
		_namespaces.declarePrefix(prefix, namespaceURI);
}

⌨️ 快捷键说明

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