--- a/src/CLIParser.h Wed Jul 24 15:53:42 2019 +0200
+++ b/src/CLIParser.h Wed Jul 24 21:29:56 2019 +0200
@@ -56,6 +56,7 @@
static const string_t OPTION_NAMESPACE;
static const string_t OPTION_RELATION;
+ static const string_t OPTION_NAME_IS_XPATH;
static const string_t OPTION_RECORDS;
static const string_t OPTION_ATTRIBUTE;
@@ -72,6 +73,8 @@
} else if (option == OPTION_RELATION) {
addRelation(c, currentRelation); // previous relation
currentRelation.relation = readNext(arguments, i);
+ } else if (option == OPTION_NAME_IS_XPATH) {
+ currentRelation.nameIsXPath = true;
} else if (option == OPTION_RECORDS) {
currentRelation.xpath = readNext(arguments, i);
} else if (option == OPTION_ATTRIBUTE) {
@@ -93,6 +96,7 @@
const string_t CLIParser::OPTION_NAMESPACE = L"--namespace";
const string_t CLIParser::OPTION_RELATION = L"--relation";
+const string_t CLIParser::OPTION_NAME_IS_XPATH = L"--name-is-xpath";
const string_t CLIParser::OPTION_RECORDS = L"--records";
const string_t CLIParser::OPTION_ATTRIBUTE = L"--attribute";
--- a/src/Configuration.h Wed Jul 24 15:53:42 2019 +0200
+++ b/src/Configuration.h Wed Jul 24 21:29:56 2019 +0200
@@ -44,6 +44,7 @@
}
relpipe::writer::string_t relation;
+ relpipe::writer::boolean_t nameIsXPath = false;
relpipe::writer::string_t xpath;
std::vector<AttributeRecipe> attributes;
--- a/src/XMLTableCommand.h Wed Jul 24 15:53:42 2019 +0200
+++ b/src/XMLTableCommand.h Wed Jul 24 21:29:56 2019 +0200
@@ -28,6 +28,7 @@
#include <relpipe/writer/typedefs.h>
+#include "Configuration.h"
namespace relpipe {
namespace in {
@@ -37,29 +38,36 @@
class XMLCommand {
private:
+ std::wstring_convert<codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
public:
- void process(std::istream& input, std::ostream& output) {
-
+ void process(std::istream& input, std::ostream& output, Configuration& configuration) {
+ std::shared_ptr<RelationalWriter> writer(Factory::create(output));
xmlpp::DomParser parser;
parser.parse_stream(input);
- xmlpp::Document* d = parser.get_document();
- xmlpp::Element* r = d->get_root_node();
-
- xmlpp::Node::PrefixNsMap m;
- m["rp"] = "tag:globalcode.info,2018:relpipe";
+ xmlpp::Element* root = parser.get_document()->get_root_node();
- output << "root: " << r->get_name() << std::endl;
-
- for (xmlpp::Node* n : r->find("//rp:attribute", m)) {
-
- output << "node:" << n->get_name() << std::endl;
-
+ xmlpp::Node::PrefixNsMap ns;
+ for (int i = 0; i < configuration.namespaceMappings.size(); i++) {
+ std::string prefix = convertor.to_bytes(configuration.namespaceMappings[i]);
+ std::string uri = convertor.to_bytes(configuration.namespaceMappings[++i]);
+ ns[prefix] = uri;
}
-
+ for (const RelationConfiguration& r : configuration.relationConfigurations) {
+ std::vector<relpipe::writer::AttributeMetadata> attributesMetadata;
+ for (AttributeRecipe a : r.attributes) attributesMetadata.push_back(AttributeMetadata{a.name, a.type});
+ relpipe::writer::string_t name = r.nameIsXPath ? convertor.from_bytes(root->eval_to_string(convertor.to_bytes(r.relation), ns)) : r.relation;
+ writer->startRelation(name, attributesMetadata, true);
+ for (xmlpp::Node* n : root->find(convertor.to_bytes(r.xpath), ns)) {
+ for (AttributeRecipe a : r.attributes) {
+ // TODO: convert to bytes only once
+ writer->writeAttribute(convertor.from_bytes(n->eval_to_string(convertor.to_bytes(a.xpath), ns)));
+ }
+ }
+ }
}
};
--- a/src/relpipe-in-xmltable.cpp Wed Jul 24 15:53:42 2019 +0200
+++ b/src/relpipe-in-xmltable.cpp Wed Jul 24 21:29:56 2019 +0200
@@ -50,7 +50,7 @@
CLIParser cliParser;
Configuration configuration = cliParser.parse(cli.arguments());
XMLCommand command;
- command.process(cin, cout);
+ command.process(cin, cout, configuration);
resultCode = CLI::EXIT_CODE_SUCCESS;
} catch (RelpipeWriterException& e) {
fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str());