📄 xmlwriter.cpp
字号:
//// XMLWriter.cpp//// $Id: //poco/1.2/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 = """;const std::string XMLWriter::MARKUP_APOSENC = "'";const std::string XMLWriter::MARKUP_AMPENC = "&";const std::string XMLWriter::MARKUP_LTENC = "<";const std::string XMLWriter::MARKUP_GTENC = ">";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#endifXMLWriter::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"); _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){ 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){ 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;}void XMLWriter::characters(const XMLChar ch[], int start, int length){ 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);}void XMLWriter::endPrefixMapping(const XMLString& prefix)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -