# HG changeset patch # User František Kučera # Date 1563996596 -7200 # Node ID 0d3eb5129582878ca800b5ab3241d5f2907a3eb9 # Parent 7d6ac51c0d48e2ed3d566ce49e03400820b21f20 convert arbitrary XML to one or more relations diff -r 7d6ac51c0d48 -r 0d3eb5129582 src/CLIParser.h --- 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"; diff -r 7d6ac51c0d48 -r 0d3eb5129582 src/Configuration.h --- 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 attributes; diff -r 7d6ac51c0d48 -r 0d3eb5129582 src/XMLTableCommand.h --- 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 +#include "Configuration.h" namespace relpipe { namespace in { @@ -37,29 +38,36 @@ class XMLCommand { private: + std::wstring_convert> 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 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 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))); + } + } + } } }; diff -r 7d6ac51c0d48 -r 0d3eb5129582 src/relpipe-in-xmltable.cpp --- 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());