src/XMLCommand.h
branchv_0
changeset 5 e5cf88ce91ac
parent 4 1363ec0879ca
child 6 be83e0f457a8
equal deleted inserted replaced
4:1363ec0879ca 5:e5cf88ce91ac
    24 #include <algorithm>
    24 #include <algorithm>
    25 
    25 
    26 #include <xercesc/sax2/SAX2XMLReader.hpp>
    26 #include <xercesc/sax2/SAX2XMLReader.hpp>
    27 #include <xercesc/sax2/XMLReaderFactory.hpp>
    27 #include <xercesc/sax2/XMLReaderFactory.hpp>
    28 #include <xercesc/sax2/DefaultHandler.hpp>
    28 #include <xercesc/sax2/DefaultHandler.hpp>
       
    29 #include <xercesc/sax2/Attributes.hpp>
    29 #include <xercesc/util/XMLString.hpp>
    30 #include <xercesc/util/XMLString.hpp>
    30 
    31 
    31 #include <relpipe/writer/typedefs.h>
    32 #include <relpipe/writer/typedefs.h>
    32 
    33 
    33 #include "StreamInputSource.h"
    34 #include "StreamInputSource.h"
    44 
    45 
    45 	class RelpipeSaxHandler : public xercesc::DefaultHandler {
    46 	class RelpipeSaxHandler : public xercesc::DefaultHandler {
    46 	private:
    47 	private:
    47 		unique_ptr<RelationalWriter> writer;
    48 		unique_ptr<RelationalWriter> writer;
    48 
    49 
       
    50 		std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
       
    51 
       
    52 		string_t toString(const XMLCh * const chars) {
       
    53 			// XMLCh = char16_t
       
    54 			// „All XML data is handled within Xerces-C++ as strings of XMLCh characters. Regardless of the size of the type chosen, the data stored in variables of type XMLCh will always be utf-16 encoded values.“
       
    55 			// see https://xerces.apache.org/xerces-c/program-others-3.html
       
    56 			// other solution (depends on boost): https://flylib.com/books/en/2.131.1/working_with_xerces_strings.html
       
    57 
       
    58 			// TODO: review this text conversion and test on various platforms
       
    59 			char* x = XMLString::transcode(chars);
       
    60 			string s = string(x);
       
    61 			XMLString::release(&x);
       
    62 			return convertor.from_bytes(s);
       
    63 		}
       
    64 
    49 	public:
    65 	public:
    50 
    66 
    51 		RelpipeSaxHandler(std::ostream& output) : DefaultHandler(), writer(Factory::create(output)) {
    67 		RelpipeSaxHandler(std::ostream& output) : DefaultHandler(), writer(Factory::create(output)) {
    52 		}
    68 		}
    53 
    69 
    54 		void startDocument() override {
    70 		void startDocument() override {
    55 			//XMLString::
    71 			//XMLString::
    56 			// TODO: remove demo
    72 			// TODO: remove demo
    57 			writer->startRelation(L"xml",{
    73 			writer->startRelation(L"xml",{
    58 				{L"event", TypeId::STRING},
    74 				{L"event", TypeId::STRING},
    59 				{L"data", TypeId::STRING},
    75 				{L"uri", TypeId::STRING},
       
    76 				{L"localname", TypeId::STRING},
       
    77 				{L"qname", TypeId::STRING},
       
    78 				{L"chars", TypeId::STRING}
    60 			}, true);
    79 			}, true);
    61 		}
    80 		}
    62 
    81 
    63 		void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const Attributes& attrs) override {
    82 		void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const Attributes& attrs) override {
    64 			writer->writeAttribute(L"startElement");
    83 			writer->writeAttribute(L"startElement");
       
    84 			writer->writeAttribute(toString(uri));
       
    85 			writer->writeAttribute(toString(localname));
       
    86 			writer->writeAttribute(toString(qname));
    65 			writer->writeAttribute(L"");
    87 			writer->writeAttribute(L"");
       
    88 
       
    89 			for (int i = 0; i < attrs.getLength(); i++) {
       
    90 				writer->writeAttribute(L"attribute");
       
    91 				writer->writeAttribute(toString(attrs.getURI(i)));
       
    92 				writer->writeAttribute(toString(attrs.getLocalName(i)));
       
    93 				writer->writeAttribute(toString(attrs.getQName(i)));
       
    94 				writer->writeAttribute(toString(attrs.getValue(i)));
       
    95 			}
    66 		}
    96 		}
    67 
    97 
    68 		void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname) override {
    98 		void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname) override {
    69 			writer->writeAttribute(L"endElement");
    99 			writer->writeAttribute(L"endElement");
       
   100 			writer->writeAttribute(toString(uri));
       
   101 			writer->writeAttribute(toString(localname));
       
   102 			writer->writeAttribute(toString(qname));
    70 			writer->writeAttribute(L"");
   103 			writer->writeAttribute(L"");
    71 		}
   104 		}
    72 
   105 
    73 		void characters(const XMLCh * const chars, const XMLSize_t length) override {
   106 		void characters(const XMLCh * const chars, const XMLSize_t length) override {
    74 			writer->writeAttribute(L"characters");
   107 			writer->writeAttribute(L"characters");
    75 			writer->writeAttribute(to_wstring(length));
   108 			writer->writeAttribute(L"");
       
   109 			writer->writeAttribute(L"");
       
   110 			writer->writeAttribute(L"");
       
   111 			writer->writeAttribute(toString(chars));
       
   112 		}
       
   113 
       
   114 		void comment(const XMLCh * const chars, const XMLSize_t length) override {
       
   115 			writer->writeAttribute(L"comment");
       
   116 			writer->writeAttribute(L"");
       
   117 			writer->writeAttribute(L"");
       
   118 			writer->writeAttribute(L"");
       
   119 			writer->writeAttribute(toString(chars));
       
   120 		}
       
   121 
       
   122 		void startCDATA() override {
       
   123 			writer->writeAttribute(L"startCDATA");
       
   124 			writer->writeAttribute(L"");
       
   125 			writer->writeAttribute(L"");
       
   126 			writer->writeAttribute(L"");
       
   127 			writer->writeAttribute(L"");
       
   128 		}
       
   129 
       
   130 		void endCDATA() override {
       
   131 			writer->writeAttribute(L"endCDATA");
       
   132 			writer->writeAttribute(L"");
       
   133 			writer->writeAttribute(L"");
       
   134 			writer->writeAttribute(L"");
       
   135 			writer->writeAttribute(L"");
    76 		}
   136 		}
    77 
   137 
    78 		void endDocument() override {
   138 		void endDocument() override {
    79 			writer->writeAttribute(L"endDocument");
   139 			writer->writeAttribute(L"endDocument");
       
   140 			writer->writeAttribute(L"");
       
   141 			writer->writeAttribute(L"");
       
   142 			writer->writeAttribute(L"");
    80 			writer->writeAttribute(L"");
   143 			writer->writeAttribute(L"");
    81 		}
   144 		}
    82 
   145 
    83 	};
   146 	};
    84 
   147 
    87 	void process(std::istream& input, std::ostream& output) {
   150 	void process(std::istream& input, std::ostream& output) {
    88 		XMLPlatformUtils::Initialize();
   151 		XMLPlatformUtils::Initialize();
    89 		unique_ptr<SAX2XMLReader> parser(XMLReaderFactory::createXMLReader());
   152 		unique_ptr<SAX2XMLReader> parser(XMLReaderFactory::createXMLReader());
    90 		parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
   153 		parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
    91 		parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
   154 		parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
       
   155 		// TODO: optional unbuffered mode for more fluent output?
       
   156 		// http://xerces.apache.org/xerces-c/program-sax2-3.html#SAX2Features
       
   157 		// parser->setProperty(XMLUni::fgXercesLowWaterMark, ...);
       
   158 		// parser->setInputBufferSize(...);
    92 
   159 
    93 		RelpipeSaxHandler saxHandler(output);
   160 		RelpipeSaxHandler saxHandler(output);
    94 		parser->setContentHandler(&saxHandler);
   161 		parser->setContentHandler(&saxHandler);
       
   162 		parser->setLexicalHandler(&saxHandler); // TODO: remove – needed only for comments
    95 		parser->setErrorHandler(&saxHandler);
   163 		parser->setErrorHandler(&saxHandler);
    96 
   164 
    97 		StreamInputSource inputSource(input);
   165 		StreamInputSource inputSource(input);
    98 
   166 
    99 		parser->parse(inputSource);
   167 		parser->parse(inputSource);