src/XMLCommand.h
branchv_0
changeset 8 14e14a5db027
parent 7 85741b08db48
child 15 177321664baf
equal deleted inserted replaced
7:85741b08db48 8:14e14a5db027
     1 /**
     1 /**
     2  * Relational pipes
     2  * Relational pipes
     3  * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
     3  * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
     4  *
     4  *
     5  * This program is free software: you can redistribute it and/or modify
     5  * This program is free software: you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation, either version 3 of the License, or
     7  * the Free Software Foundation, either version 3 of the License, or
     8  * (at your option) any later version.
     8  * (at your option) any later version.
    18 #pragma once
    18 #pragma once
    19 
    19 
    20 #include <cstdlib>
    20 #include <cstdlib>
    21 #include <iostream>
    21 #include <iostream>
    22 #include <string>
    22 #include <string>
       
    23 #include <sstream>
    23 #include <vector>
    24 #include <vector>
    24 #include <algorithm>
    25 #include <algorithm>
    25 
    26 
    26 #include <xercesc/sax2/SAX2XMLReader.hpp>
    27 #include <xercesc/sax2/SAX2XMLReader.hpp>
    27 #include <xercesc/sax2/XMLReaderFactory.hpp>
    28 #include <xercesc/sax2/XMLReaderFactory.hpp>
    44 class XMLCommand {
    45 class XMLCommand {
    45 private:
    46 private:
    46 
    47 
    47 	class RelpipeSaxHandler : public xercesc::DefaultHandler {
    48 	class RelpipeSaxHandler : public xercesc::DefaultHandler {
    48 	private:
    49 	private:
       
    50 		const wstring XMLNS = L"tag:globalcode.info,2018:relpipe";
    49 		unique_ptr<RelationalWriter> writer;
    51 		unique_ptr<RelationalWriter> writer;
    50 		XercesStringConvertor xConvertor;
    52 		XercesStringConvertor xConvertor;
       
    53 		wstring currentRelationName;
       
    54 		vector<AttributeMetadata> currentAttributes;
       
    55 		wstringstream currentValue;
       
    56 
       
    57 		void resetCurrentValue() {
       
    58 			currentValue.str(L"");
       
    59 			currentValue.clear();
       
    60 		}
       
    61 
       
    62 		string_t getAttributeName(const Attributes& attrs, string_t uri, string_t localname) {
       
    63 			// TODO: less string conversions, better performance
       
    64 			XMLCh* xUri = xConvertor.toXercesString(uri);
       
    65 			XMLCh* xLocalName = xConvertor.toXercesString(localname);
       
    66 			string_t value = xConvertor.toString(attrs.getValue(xUri, xLocalName));
       
    67 			XMLString::release(&xUri);
       
    68 			XMLString::release(&xLocalName);
       
    69 			return value;
       
    70 		}
       
    71 
       
    72 		void startElement(const string_t uri, const string_t localname, const string_t qname, const Attributes& attrs) {
       
    73 			if (uri == XMLNS) {
       
    74 				if (localname == L"name") {
       
    75 					resetCurrentValue();
       
    76 				} else if (localname == L"attributes-metadata") {
       
    77 					currentAttributes.clear();
       
    78 				} else if (localname == L"attribute-metadata") {
       
    79 					AttributeMetadata am;
       
    80 					am.attributeName = getAttributeName(attrs, L"", L"name");
       
    81 					am.typeId = writer->toTypeId(getAttributeName(attrs, L"", L"type"));
       
    82 					currentAttributes.push_back(am);
       
    83 				} else if (localname == L"attribute") {
       
    84 					resetCurrentValue();
       
    85 				}
       
    86 			}
       
    87 		}
       
    88 
       
    89 		void endElement(const string_t uri, const string_t localname, const string_t qname) {
       
    90 			if (uri == XMLNS) {
       
    91 				if (localname == L"name") {
       
    92 					currentRelationName = currentValue.str();
       
    93 				} else if (localname == L"attributes-metadata") {
       
    94 					writer->startRelation(currentRelationName, currentAttributes, true);
       
    95 				} else if (localname == L"attribute") {
       
    96 					writer->writeAttribute(currentValue.str());
       
    97 				}
       
    98 			}
       
    99 		}
       
   100 
       
   101 		void characters(const string_t chars) {
       
   102 			currentValue << chars.c_str();
       
   103 		}
    51 
   104 
    52 	public:
   105 	public:
    53 
   106 
    54 		RelpipeSaxHandler(std::ostream& output) : DefaultHandler(), writer(Factory::create(output)) {
   107 		RelpipeSaxHandler(std::ostream& output) : DefaultHandler(), writer(Factory::create(output)) {
    55 		}
   108 		}
    56 
   109 
    57 		void startDocument() override {
   110 		virtual ~RelpipeSaxHandler() {
    58 			//XMLString::
   111 
    59 			// TODO: remove demo
       
    60 			writer->startRelation(L"xml",{
       
    61 				{L"event", TypeId::STRING},
       
    62 				{L"uri", TypeId::STRING},
       
    63 				{L"localname", TypeId::STRING},
       
    64 				{L"qname", TypeId::STRING},
       
    65 				{L"chars", TypeId::STRING}
       
    66 			}, true);
       
    67 		}
   112 		}
    68 
   113 
    69 		void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const Attributes& attrs) override {
   114 		void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const Attributes& attrs) override {
    70 			writer->writeAttribute(L"startElement");
   115 			startElement(xConvertor.toString(uri), xConvertor.toString(localname), xConvertor.toString(qname), attrs);
    71 			writer->writeAttribute(xConvertor.toString(uri));
       
    72 			writer->writeAttribute(xConvertor.toString(localname));
       
    73 			writer->writeAttribute(xConvertor.toString(qname));
       
    74 			writer->writeAttribute(L"");
       
    75 
       
    76 			for (int i = 0; i < attrs.getLength(); i++) {
       
    77 				writer->writeAttribute(L"attribute");
       
    78 				writer->writeAttribute(xConvertor.toString(attrs.getURI(i)));
       
    79 				writer->writeAttribute(xConvertor.toString(attrs.getLocalName(i)));
       
    80 				writer->writeAttribute(xConvertor.toString(attrs.getQName(i)));
       
    81 				writer->writeAttribute(xConvertor.toString(attrs.getValue(i)));
       
    82 			}
       
    83 		}
   116 		}
    84 
   117 
    85 		void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname) override {
   118 		void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname) override {
    86 			writer->writeAttribute(L"endElement");
   119 			endElement(xConvertor.toString(uri), xConvertor.toString(localname), xConvertor.toString(qname));
    87 			writer->writeAttribute(xConvertor.toString(uri));
       
    88 			writer->writeAttribute(xConvertor.toString(localname));
       
    89 			writer->writeAttribute(xConvertor.toString(qname));
       
    90 			writer->writeAttribute(L"");
       
    91 		}
   120 		}
    92 
   121 
    93 		void characters(const XMLCh * const chars, const XMLSize_t length) override {
   122 		void characters(const XMLCh * const chars, const XMLSize_t length) override {
    94 			writer->writeAttribute(L"characters");
   123 			characters(xConvertor.toString(chars));
    95 			writer->writeAttribute(L"");
       
    96 			writer->writeAttribute(L"");
       
    97 			writer->writeAttribute(L"");
       
    98 			writer->writeAttribute(xConvertor.toString(chars));
       
    99 		}
       
   100 
       
   101 		void comment(const XMLCh * const chars, const XMLSize_t length) override {
       
   102 			writer->writeAttribute(L"comment");
       
   103 			writer->writeAttribute(L"");
       
   104 			writer->writeAttribute(L"");
       
   105 			writer->writeAttribute(L"");
       
   106 			writer->writeAttribute(xConvertor.toString(chars));
       
   107 		}
       
   108 
       
   109 		void startCDATA() override {
       
   110 			writer->writeAttribute(L"startCDATA");
       
   111 			writer->writeAttribute(L"");
       
   112 			writer->writeAttribute(L"");
       
   113 			writer->writeAttribute(L"");
       
   114 			writer->writeAttribute(L"");
       
   115 		}
       
   116 
       
   117 		void endCDATA() override {
       
   118 			writer->writeAttribute(L"endCDATA");
       
   119 			writer->writeAttribute(L"");
       
   120 			writer->writeAttribute(L"");
       
   121 			writer->writeAttribute(L"");
       
   122 			writer->writeAttribute(L"");
       
   123 		}
       
   124 
       
   125 		void processingInstruction(const XMLCh * const target, const XMLCh * const data) override {
       
   126 			writer->writeAttribute(L"processingInstruction");
       
   127 			writer->writeAttribute(L"");
       
   128 			writer->writeAttribute(L"");
       
   129 			writer->writeAttribute(xConvertor.toString(target));
       
   130 			writer->writeAttribute(xConvertor.toString(data));
       
   131 		}
       
   132 
       
   133 		void endDocument() override {
       
   134 			writer->writeAttribute(L"endDocument");
       
   135 			writer->writeAttribute(L"");
       
   136 			writer->writeAttribute(L"");
       
   137 			writer->writeAttribute(L"");
       
   138 			writer->writeAttribute(L"");
       
   139 		}
   124 		}
   140 
   125 
   141 	};
   126 	};
   142 
   127 
   143 public:
   128 public:
   152 		// parser->setProperty(XMLUni::fgXercesLowWaterMark, ...);
   137 		// parser->setProperty(XMLUni::fgXercesLowWaterMark, ...);
   153 		// parser->setInputBufferSize(...);
   138 		// parser->setInputBufferSize(...);
   154 
   139 
   155 		RelpipeSaxHandler saxHandler(output);
   140 		RelpipeSaxHandler saxHandler(output);
   156 		parser->setContentHandler(&saxHandler);
   141 		parser->setContentHandler(&saxHandler);
   157 		parser->setLexicalHandler(&saxHandler); // TODO: remove – needed only for comments
       
   158 		parser->setErrorHandler(&saxHandler);
   142 		parser->setErrorHandler(&saxHandler);
   159 
   143 
   160 		StreamInputSource inputSource(input);
   144 		StreamInputSource inputSource(input);
   161 
   145 
   162 		parser->parse(inputSource);
   146 		parser->parse(inputSource);