--- a/src/OdsHandler.h Fri Dec 07 12:53:43 2018 +0100
+++ b/src/OdsHandler.h Fri Dec 07 14:46:40 2018 +0100
@@ -39,7 +39,14 @@
class OdsHandler : public handlers::RelationalReaderStringHadler {
private:
std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // XML output will be always in UTF-8
- const char* INDENT = "\t";
+
+ // TODO: refactor and move common XML functions to relpipe-lib-xml
+ const char* INDENT_1 = "\t";
+ const char* INDENT_2 = "\t\t";
+ const char* INDENT_3 = "\t\t\t";
+ const char* INDENT_4 = "\t\t\t\t";
+ const char* INDENT_5 = "\t\t\t\t\t";
+ const char* INDENT_6 = "\t\t\t\t\t\t";
std::ostream &output;
@@ -50,6 +57,8 @@
integer_t columnCount = 0;
integer_t relationCount = 0;
+ // TODO: refactor and move common XML functions to relpipe-lib-xml
+
const std::string escapeXmlText(const string_t &value) {
std::wstringstream result;
@@ -85,50 +94,68 @@
if (relationCount == 0) {
output << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
- output << "<pipe TODO=\"ods\">" << std::endl;
- // TODO: xmlns
+ output << "<office:document" << std::endl;
+ output << INDENT_1 << "xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" << std::endl;
+ output << INDENT_1 << "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"" << std::endl;
+ output << INDENT_1 << "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"" << std::endl;
+ output << INDENT_1 << "office:mimetype=\"application/vnd.oasis.opendocument.spreadsheet\"" << std::endl;
+ output << INDENT_1 << "office:version=\"1.2\">" << std::endl;
+
+ output << INDENT_1 << "<office:body>" << std::endl;
+ output << INDENT_2 << "<office:spreadsheet>" << std::endl;
+
} else {
- output << INDENT << INDENT << "</record>" << std::endl;
- output << INDENT << "</relation>" << std::endl;
+ output << INDENT_4 << "</table:table-row>" << std::endl;
+ output << INDENT_3 << "</table:table>" << std::endl;
}
relationCount++;
- output << INDENT << "<relation>" << std::endl;
-
- output << INDENT << INDENT << "<name>" << escapeXmlText(name) << "</name>" << std::endl;
+ // TODO: rename relations with same names
+ output << INDENT_3 << "<table:table table:name=\"" << escapeXmlText(name) << "\">" << std::endl;
columnCount = attributes.size();
columnTypes.resize(columnCount);
columnTypeCodes.resize(columnCount);
columnNames.resize(columnCount);
+
+ output << INDENT_4 << "<table:table-row>" << std::endl;
for (int i = 0; i < attributes.size(); i++) {
columnNames[i] = attributes[i].getAttributeName();
columnTypes[i] = attributes[i].getTypeId();
columnTypeCodes[i] = attributes[i].getTypeName();
+
+ output << INDENT_5 << "<table:table-cell>" << std::endl;
+ output << INDENT_6 << "<text:p>";
+ output << escapeXmlText(columnNames[i]);
+ output << "</text:p>" << std::endl;
+ output << INDENT_5 << "</table:table-cell>" << std::endl;
}
-
- // TODO: print attribute metadata
+ output << INDENT_4 << "</table:table-row>" << std::endl;
+
}
void attribute(const string_t& value) override {
integer_t i = valueCount % columnCount;
- if (i == 0 && valueCount) output << INDENT << INDENT << "</record>" << std::endl;
- if (i == 0) output << INDENT << INDENT << "<record>" << std::endl;
+ if (i == 0 && valueCount) output << INDENT_4 << "</table:table-row>" << std::endl;
+ if (i == 0) output << INDENT_4 << "<table:table-row>" << std::endl;
valueCount++;
- // TODO: print attribute metadata (optional)
- output << INDENT << INDENT << INDENT << "<attribute>";
+ output << INDENT_5 << "<table:table-cell>" << std::endl;
+ output << INDENT_6 << "<text:p>";
output << escapeXmlText(value);
- output << "</attribute>" << std::endl;
+ output << "</text:p>" << std::endl;
+ output << INDENT_5 << "</table:table-cell>" << std::endl;
}
void endOfPipe() {
- if (valueCount) output << INDENT << INDENT << "</record>" << std::endl;
- if (relationCount) output << INDENT << "</relation>" << std::endl;
- output << "</pipe>" << std::endl;
+ if (valueCount) output << INDENT_4 << "</table:table-row>" << std::endl;
+ if (relationCount) output << INDENT_3 << "</table:table>" << std::endl;
+ output << INDENT_2 << "</office:spreadsheet>" << std::endl;
+ output << INDENT_1 << "</office:body>" << std::endl;
+ output << "</office:document>" << std::endl;
}