src/XPathHandler.h
branchv_0
changeset 8 9f95cfd68f25
parent 7 7f2d09c3b1de
equal deleted inserted replaced
7:7f2d09c3b1de 8:9f95cfd68f25
   108 			return L"";
   108 			return L"";
   109 		}
   109 		}
   110 	}
   110 	}
   111 
   111 
   112 	xmlpp::Element* findSingleElement(const xmlpp::NodeSet& nodeset) {
   112 	xmlpp::Element* findSingleElement(const xmlpp::NodeSet& nodeset) {
       
   113 		// TODO: Allow multiple elements and attributes and wrap them? Like in relpipe-in-xmltable --raw-xml-attribute-wrapper  --raw-xml-nodelist-wrapper
   113 		if (nodeset.empty()) return nullptr;
   114 		if (nodeset.empty()) return nullptr;
   114 		else if (nodeset.size() > 1) throw std::invalid_argument("XPath should find one or zero elements.");
   115 		else if (nodeset.size() > 1) throw std::invalid_argument("XPath should find one or zero elements.");
   115 		else if (xmlpp::Element * element = dynamic_cast<xmlpp::Element*> (nodeset[0])) return element;
   116 		else if (xmlpp::Element * element = dynamic_cast<xmlpp::Element*> (nodeset[0])) return element;
   116 		else if (nodeset[0]->get_path() == "/") return findSingleElement(nodeset[0]->find("*")); // support also "/" not only "/*" expressions (return root element in both cases)
   117 		else if (nodeset[0]->get_path() == "/") return findSingleElement(nodeset[0]->find("*")); // support also "/" not only "/*" expressions (return root element in both cases)
   117 		else throw std::invalid_argument("XPath should find an element, not other kinds of nodes.");
   118 		else throw std::invalid_argument("XPath should find an element, not other kinds of nodes.");
   168 		} else {
   169 		} else {
   169 			if (isPrependingInputAttributes()) copyInputAttributesToOutput();
   170 			if (isPrependingInputAttributes()) copyInputAttributesToOutput();
   170 			for (auto oa : currentRelationConfiguration->outputAttributes) currentWriterMetadata.push_back({oa.name, oa.type});
   171 			for (auto oa : currentRelationConfiguration->outputAttributes) currentWriterMetadata.push_back({oa.name, oa.type});
   171 			if (isAppendingInputAttributes()) copyInputAttributesToOutput();
   172 			if (isAppendingInputAttributes()) copyInputAttributesToOutput();
   172 
   173 
       
   174 			// TODO: better metadata structure
       
   175 			// TODO: optional namespaces
   173 			dom.create_root_node("relpipe-tr-xpath");
   176 			dom.create_root_node("relpipe-tr-xpath");
   174 			dom.get_root_node()->add_child("relation-name")->add_child_text(s2x(name));
   177 			dom.get_root_node()->add_child("relation-name")->add_child_text(s2x(name));
   175 			resetRecordElement();
   178 			resetRecordElement();
   176 		}
   179 		}
   177 
   180 
   192 					xmlpp::DomParser attributeParser;
   195 					xmlpp::DomParser attributeParser;
   193 					attributeParser.parse_memory(s2x(value));
   196 					attributeParser.parse_memory(s2x(value));
   194 					attributeElement->import_node(attributeParser.get_document()->get_root_node(), true);
   197 					attributeElement->import_node(attributeParser.get_document()->get_root_node(), true);
   195 				}
   198 				}
   196 			} else {
   199 			} else {
       
   200 				// TODO: better boolean mapping? Missing text node will be evaluated as false(), however the expression still had to be "someAttribute/text()" because "someAttribute" will be evaluated as true() because the "someAttribute" element is present.
   197 				attributeElement->add_child_text(s2x(value));
   201 				attributeElement->add_child_text(s2x(value));
   198 			}
   202 			}
   199 
   203 
   200 			if (currentAttributeIndex == 0) {
   204 			if (currentAttributeIndex == 0) {
   201 				recordElement->set_attribute("number", std::to_string(currentRecordNumber));
   205 				recordElement->set_attribute("number", std::to_string(currentRecordNumber));