include/relpipe/xmlwriter/XMLWriter.h
author František Kučera <franta-hg@frantovo.cz>
Sun, 06 Jan 2019 22:15:37 +0100
branchv_0
changeset 2 f21d6ae71bf0
parent 1 7d3081e51970
child 3 edbebc6163e3
permissions -rw-r--r--
move common XML code to relpipe-lib-xmlwriter (a header-only library)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     1
/**
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     2
 * Relational pipes
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     3
 * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     4
 *
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     7
 * the Free Software Foundation, either version 3 of the License, or
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     8
 * (at your option) any later version.
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
     9
 *
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    10
 * This program is distributed in the hope that it will be useful,
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    13
 * GNU General Public License for more details.
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    14
 *
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    15
 * You should have received a copy of the GNU General Public License
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    16
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    17
 */
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    18
#pragma once
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    19
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    20
#include <iostream>
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    21
#include <sstream>
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    22
#include <string>
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    23
#include <vector>
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    24
#include <codecvt>
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    25
#include <locale>
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    26
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    27
#include "RelpipeXMLWriterException.h"
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    28
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    29
using namespace std;
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    30
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    31
namespace relpipe {
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    32
namespace xmlwriter {
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    33
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    34
/**
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    35
 * A simple library for writing XML streams.
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    36
 * 
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    37
 * Does:
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    38
 *  - convert wstring values to UTF-8
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    39
 *  - escape values of text nodes and attributes
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    40
 *  - indent elements
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    41
 *  - preserve whitespace of text nodes
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    42
 *  - in comments: replace - with –
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    43
 * Does not:
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    44
 *  - understand XML namespaces:
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    45
 *     - handles xmlns:x="y" as ordinary attributes
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    46
 *     - thus can not check whether elements/attributes belong to an declared namespace
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    47
 *     - thus can generate invalid XML – namespaces and their prefixes must be checked on the caller side
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    48
 */
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    49
class XMLWriter {
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
    50
private:
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    51
	const char* INDENT = "\t";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    52
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    53
	ostream& output;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    54
	wstring_convert<codecvt_utf8<wchar_t>> convertor; // XML output will be always in UTF-8
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    55
	vector<wstring> treePosition;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    56
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    57
	const string escapeXmlText(const wstring& value) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    58
		// TODO: really bad performance → rewrite
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    59
		// 72 % of whole relpipe-out-xml according to valgrind/callgrind
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    60
		// Moved here from XmlHandler.h (relpipe-out-xml).
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    61
		std::wstringstream result;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    62
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    63
		for (auto & ch : value) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    64
			switch (ch) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    65
				case L'&': result << L"&amp;";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    66
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    67
				case L'<': result << L"&lt;";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    68
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    69
				case L'>': result << L"&gt;";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    70
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    71
				case L'\'': result << L"&apos;"; // TODO: escape ' and " only in attributes
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    72
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    73
				case L'"': result << L"&quot;"; // TODO: escape ' and " only in attributes
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    74
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    75
				default: result << ch;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    76
			}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    77
		}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    78
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    79
		return convertor.to_bytes(result.str());
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    80
	}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    81
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    82
	const string escapeXmlAttribute(const wstring& value) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    83
		// TODO: escaping of ' is not necessary.
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    84
		return escapeXmlText(value);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    85
	}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    86
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    87
	const string escapeComment(const wstring& value) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    88
		// TODO: really bad performance → rewrite
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    89
		// 72 % of whole relpipe-out-xml according to valgrind/callgrind
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    90
		std::wstringstream result;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    91
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    92
		for (auto & ch : value) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    93
			switch (ch) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    94
				case L'-': result << L"–";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    95
					break;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    96
				default: result << ch;
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    97
			}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    98
		}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    99
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   100
		return convertor.to_bytes(result.str());
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   101
	}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   102
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   103
	void checkName(const wstring& name) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   104
		// FIXME: throw exception on invalid names
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   105
	}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   106
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   107
	void writeAttributes(const vector<wstring>& attributes) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   108
		if (attributes.size() % 2) throw RelpipeXMLWriterException(L"attributes vector must contain name/value pairs (even number of elements)");
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   109
		for (int i = 0; i < attributes.size(); i = i + 2) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   110
			wstring name = attributes[i];
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   111
			wstring value = attributes[i + 1];
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   112
			checkName(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   113
			output << " " << convertor.to_bytes(name) << "=\"" << escapeXmlAttribute(value) << "\"";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   114
		}
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   115
	}
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   116
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   117
public:
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   118
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   119
	XMLWriter(std::ostream& output) : output(output) {
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   120
		output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   121
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   122
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   123
	virtual ~XMLWriter() {
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   124
		output.flush();
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   125
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   126
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   127
	void writeStartElement(const wstring& name, const vector<wstring>& attributes = {}) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   128
		// FIXME: indentation
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   129
		checkName(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   130
		treePosition.push_back(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   131
		output << "<" << convertor.to_bytes(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   132
		writeAttributes(attributes);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   133
		output << ">";
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   134
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   135
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   136
	void writeEndElement() {
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   137
		// FIXME: indentation
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   138
		if (treePosition.empty()) throw RelpipeXMLWriterException(L"unable to close element – all elements are already closed");
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   139
		output << "</" << convertor.to_bytes(treePosition.back()) << ">";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   140
		treePosition.pop_back();
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   141
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   142
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   143
	void writeEmptyElement(const wstring& name, const vector<wstring>& attributes = {}) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   144
		// FIXME: indentation
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   145
		checkName(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   146
		output << "<" << convertor.to_bytes(name);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   147
		writeAttributes(attributes);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   148
		output << "/>";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   149
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   150
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   151
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   152
	void writeTextElement(const wstring& name, const vector<wstring>& attributes, const wstring& text) {
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   153
		writeStartElement(name, attributes);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   154
		writeCharacters(text);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   155
		writeEndElement();
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   156
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   157
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   158
	void writeCharacters(const wstring& text) {
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   159
		output << escapeXmlText(text);
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   160
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   161
2
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   162
	void writeComment(const wstring& text, bool addSpaces = true) {
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   163
		output << addSpaces ? "<!-- " : "<!--";
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   164
		output << escapeComment(text);
f21d6ae71bf0 move common XML code to relpipe-lib-xmlwriter (a header-only library)
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
   165
		output << addSpaces ? " -->" : "-->";
1
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   166
	}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   167
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   168
};
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   169
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   170
}
7d3081e51970 class skeleton
František Kučera <franta-hg@frantovo.cz>
parents: 0
diff changeset
   171
}