--- a/src/XMLCommand.h Fri Jan 11 16:20:25 2019 +0100
+++ b/src/XMLCommand.h Fri Jan 11 17:41:56 2019 +0100
@@ -1,6 +1,6 @@
/**
* Relational pipes
- * Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info)
+ * Copyright © 2019 František Kučera (Frantovo.cz, GlobalCode.info)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <iostream>
#include <string>
+#include <sstream>
#include <vector>
#include <algorithm>
@@ -46,96 +47,80 @@
class RelpipeSaxHandler : public xercesc::DefaultHandler {
private:
+ const wstring XMLNS = L"tag:globalcode.info,2018:relpipe";
unique_ptr<RelationalWriter> writer;
XercesStringConvertor xConvertor;
+ wstring currentRelationName;
+ vector<AttributeMetadata> currentAttributes;
+ wstringstream currentValue;
+
+ void resetCurrentValue() {
+ currentValue.str(L"");
+ currentValue.clear();
+ }
+
+ string_t getAttributeName(const Attributes& attrs, string_t uri, string_t localname) {
+ // TODO: less string conversions, better performance
+ XMLCh* xUri = xConvertor.toXercesString(uri);
+ XMLCh* xLocalName = xConvertor.toXercesString(localname);
+ string_t value = xConvertor.toString(attrs.getValue(xUri, xLocalName));
+ XMLString::release(&xUri);
+ XMLString::release(&xLocalName);
+ return value;
+ }
+
+ void startElement(const string_t uri, const string_t localname, const string_t qname, const Attributes& attrs) {
+ if (uri == XMLNS) {
+ if (localname == L"name") {
+ resetCurrentValue();
+ } else if (localname == L"attributes-metadata") {
+ currentAttributes.clear();
+ } else if (localname == L"attribute-metadata") {
+ AttributeMetadata am;
+ am.attributeName = getAttributeName(attrs, L"", L"name");
+ am.typeId = writer->toTypeId(getAttributeName(attrs, L"", L"type"));
+ currentAttributes.push_back(am);
+ } else if (localname == L"attribute") {
+ resetCurrentValue();
+ }
+ }
+ }
+
+ void endElement(const string_t uri, const string_t localname, const string_t qname) {
+ if (uri == XMLNS) {
+ if (localname == L"name") {
+ currentRelationName = currentValue.str();
+ } else if (localname == L"attributes-metadata") {
+ writer->startRelation(currentRelationName, currentAttributes, true);
+ } else if (localname == L"attribute") {
+ writer->writeAttribute(currentValue.str());
+ }
+ }
+ }
+
+ void characters(const string_t chars) {
+ currentValue << chars.c_str();
+ }
public:
RelpipeSaxHandler(std::ostream& output) : DefaultHandler(), writer(Factory::create(output)) {
}
- void startDocument() override {
- //XMLString::
- // TODO: remove demo
- writer->startRelation(L"xml",{
- {L"event", TypeId::STRING},
- {L"uri", TypeId::STRING},
- {L"localname", TypeId::STRING},
- {L"qname", TypeId::STRING},
- {L"chars", TypeId::STRING}
- }, true);
+ virtual ~RelpipeSaxHandler() {
+
}
void startElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname, const Attributes& attrs) override {
- writer->writeAttribute(L"startElement");
- writer->writeAttribute(xConvertor.toString(uri));
- writer->writeAttribute(xConvertor.toString(localname));
- writer->writeAttribute(xConvertor.toString(qname));
- writer->writeAttribute(L"");
-
- for (int i = 0; i < attrs.getLength(); i++) {
- writer->writeAttribute(L"attribute");
- writer->writeAttribute(xConvertor.toString(attrs.getURI(i)));
- writer->writeAttribute(xConvertor.toString(attrs.getLocalName(i)));
- writer->writeAttribute(xConvertor.toString(attrs.getQName(i)));
- writer->writeAttribute(xConvertor.toString(attrs.getValue(i)));
- }
+ startElement(xConvertor.toString(uri), xConvertor.toString(localname), xConvertor.toString(qname), attrs);
}
void endElement(const XMLCh * const uri, const XMLCh * const localname, const XMLCh * const qname) override {
- writer->writeAttribute(L"endElement");
- writer->writeAttribute(xConvertor.toString(uri));
- writer->writeAttribute(xConvertor.toString(localname));
- writer->writeAttribute(xConvertor.toString(qname));
- writer->writeAttribute(L"");
+ endElement(xConvertor.toString(uri), xConvertor.toString(localname), xConvertor.toString(qname));
}
void characters(const XMLCh * const chars, const XMLSize_t length) override {
- writer->writeAttribute(L"characters");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(xConvertor.toString(chars));
- }
-
- void comment(const XMLCh * const chars, const XMLSize_t length) override {
- writer->writeAttribute(L"comment");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(xConvertor.toString(chars));
- }
-
- void startCDATA() override {
- writer->writeAttribute(L"startCDATA");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- }
-
- void endCDATA() override {
- writer->writeAttribute(L"endCDATA");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- }
-
- void processingInstruction(const XMLCh * const target, const XMLCh * const data) override {
- writer->writeAttribute(L"processingInstruction");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(xConvertor.toString(target));
- writer->writeAttribute(xConvertor.toString(data));
- }
-
- void endDocument() override {
- writer->writeAttribute(L"endDocument");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
- writer->writeAttribute(L"");
+ characters(xConvertor.toString(chars));
}
};
@@ -154,7 +139,6 @@
RelpipeSaxHandler saxHandler(output);
parser->setContentHandler(&saxHandler);
- parser->setLexicalHandler(&saxHandler); // TODO: remove – needed only for comments
parser->setErrorHandler(&saxHandler);
StreamInputSource inputSource(input);