diff --git a/buildspec.json b/buildspec.json index 434ab96..8bb43ec 100644 --- a/buildspec.json +++ b/buildspec.json @@ -45,7 +45,7 @@ } }, "name": "obs-urlsource", - "version": "0.1.0", + "version": "0.1.1", "author": "Roy Shilkrot", "website": "https://github.com/royshil/obs-urlsource", "email": "roy.shil@gmail.com", @@ -54,4 +54,4 @@ "macosInstaller": "00000000-0000-0000-0000-000000000000", "windowsApp": "00000000-0000-0000-0000-000000000000" } -} +} \ No newline at end of file diff --git a/src/request-data.cpp b/src/request-data.cpp index 1fbdc5b..5a43f76 100644 --- a/src/request-data.cpp +++ b/src/request-data.cpp @@ -90,6 +90,33 @@ struct request_data_handler_response parse_xml(struct request_data_handler_respo return response; } +struct request_data_handler_response +parse_xml_by_xquery(struct request_data_handler_response response, + url_source_request_data *request_data) +{ + // Parse the response as XML using pugixml + pugi::xml_document doc; + pugi::xml_parse_result result = doc.load_string(response.body.c_str()); + if (!result) { + obs_log(LOG_INFO, "Failed to parse XML response: %s", result.description()); + // Return an error response + struct request_data_handler_response responseFail; + responseFail.error_message = result.description(); + responseFail.status_code = URL_SOURCE_REQUEST_PARSING_ERROR_CODE; + return responseFail; + } + // Get the output value + if (request_data->output_xquery != "") { + pugi::xpath_query query_entity(request_data->output_xquery.c_str()); + std::string s = query_entity.evaluate_string(doc); + response.body_parsed = s; + } else { + // Return the whole XML object + response.body_parsed = response.body; + } + return response; +} + struct request_data_handler_response parse_json(struct request_data_handler_response response, url_source_request_data *request_data) { @@ -276,8 +303,11 @@ struct request_data_handler_response request_data_handler(url_source_request_dat // Parse the response if (request_data->output_type == "JSON") { response = parse_json(response, request_data); - } else if (request_data->output_type == "XML" || request_data->output_type == "HTML") { + } else if (request_data->output_type == "XML (XPath)" || + request_data->output_type == "HTML") { response = parse_xml(response, request_data); + } else if (request_data->output_type == "XML (XQuery)") { + response = parse_xml_by_xquery(response, request_data); } else if (request_data->output_type == "Text") { response = parse_regex(response, request_data); } else { @@ -312,6 +342,7 @@ std::string serialize_request_data(url_source_request_data *request_data) json["output_type"] = request_data->output_type; json["output_json_path"] = request_data->output_json_path; json["output_xpath"] = request_data->output_xpath; + json["output_xquery"] = request_data->output_xquery; json["output_regex"] = request_data->output_regex; json["output_regex_flags"] = request_data->output_regex_flags; json["output_regex_group"] = request_data->output_regex_group; @@ -381,6 +412,7 @@ url_source_request_data unserialize_request_data(std::string serialized_request_ request_data.output_type = json["output_type"].get(); request_data.output_json_path = json["output_json_path"].get(); request_data.output_xpath = json["output_xpath"].get(); + request_data.output_xquery = json["output_xquery"].get(); request_data.output_regex = json["output_regex"].get(); request_data.output_regex_flags = json["output_regex_flags"].get(); request_data.output_regex_group = json["output_regex_group"].get(); diff --git a/src/request-data.h b/src/request-data.h index 9ff8558..e9b5b3e 100644 --- a/src/request-data.h +++ b/src/request-data.h @@ -29,6 +29,7 @@ struct url_source_request_data { std::string output_type; std::string output_json_path; std::string output_xpath; + std::string output_xquery; std::string output_regex; std::string output_regex_flags; std::string output_regex_group; @@ -48,6 +49,7 @@ struct url_source_request_data { output_type = std::string("text"); output_json_path = std::string(""); output_xpath = std::string(""); + output_xquery = std::string(""); output_regex = std::string(""); output_regex_flags = std::string(""); output_regex_group = std::string("0"); @@ -68,6 +70,7 @@ struct url_source_request_data { output_type = std::string(other.output_type); output_json_path = std::string(other.output_json_path); output_xpath = std::string(other.output_xpath); + output_xquery = std::string(other.output_xquery); output_regex = std::string(other.output_regex); output_regex_flags = std::string(other.output_regex_flags); output_regex_group = std::string(other.output_regex_group); @@ -88,6 +91,7 @@ struct url_source_request_data { output_type = std::string(other.output_type); output_json_path = std::string(other.output_json_path); output_xpath = std::string(other.output_xpath); + output_xquery = std::string(other.output_xquery); output_regex = std::string(other.output_regex); output_regex_flags = std::string(other.output_regex_flags); output_regex_group = std::string(other.output_regex_group); diff --git a/src/ui/RequestBuilder.cpp b/src/ui/RequestBuilder.cpp index 570021b..3338482 100644 --- a/src/ui/RequestBuilder.cpp +++ b/src/ui/RequestBuilder.cpp @@ -331,7 +331,8 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data, QComboBox *outputTypeComboBox = new QComboBox; outputTypeComboBox->addItem("Text"); outputTypeComboBox->addItem("JSON"); - outputTypeComboBox->addItem("XML"); + outputTypeComboBox->addItem("XML (XPath)"); + outputTypeComboBox->addItem("XML (XQuery)"); outputTypeComboBox->addItem("HTML"); outputTypeComboBox->setCurrentIndex( outputTypeComboBox->findText(QString::fromStdString(request_data->output_type))); @@ -345,6 +346,10 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data, outputXPathLineEdit->setText(QString::fromStdString(request_data->output_xpath)); outputXPathLineEdit->setPlaceholderText("XPath"); formOutputParsing->addRow("XPath", outputXPathLineEdit); + QLineEdit *outputXQueryLineEdit = new QLineEdit; + outputXQueryLineEdit->setText(QString::fromStdString(request_data->output_xquery)); + outputXQueryLineEdit->setPlaceholderText("XQuery"); + formOutputParsing->addRow("XQuery", outputXQueryLineEdit); QLineEdit *outputRegexLineEdit = new QLineEdit; outputRegexLineEdit->setText(QString::fromStdString(request_data->output_regex)); outputRegexLineEdit->setPlaceholderText("Regex"); @@ -362,6 +367,7 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data, // Hide all output parsing options set_form_row_visibility(formOutputParsing, outputJSONPathLineEdit, false); set_form_row_visibility(formOutputParsing, outputXPathLineEdit, false); + set_form_row_visibility(formOutputParsing, outputXQueryLineEdit, false); set_form_row_visibility(formOutputParsing, outputRegexLineEdit, false); set_form_row_visibility(formOutputParsing, outputRegexFlagsLineEdit, false); set_form_row_visibility(formOutputParsing, outputRegexGroupLineEdit, false); @@ -369,9 +375,11 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data, // Show the output parsing options for the selected output type if (outputTypeComboBox->currentText() == "JSON") { set_form_row_visibility(formOutputParsing, outputJSONPathLineEdit, true); - } else if (outputTypeComboBox->currentText() == "XML" || + } else if (outputTypeComboBox->currentText() == "XML (XPath)" || outputTypeComboBox->currentText() == "HTML") { set_form_row_visibility(formOutputParsing, outputXPathLineEdit, true); + } else if (outputTypeComboBox->currentText() == "XML (XQuery)") { + set_form_row_visibility(formOutputParsing, outputXQueryLineEdit, true); } else if (outputTypeComboBox->currentText() == "Text") { set_form_row_visibility(formOutputParsing, outputRegexLineEdit, true); set_form_row_visibility(formOutputParsing, outputRegexFlagsLineEdit, true); @@ -434,6 +442,7 @@ RequestBuilder::RequestBuilder(url_source_request_data *request_data, request_data_for_saving->output_json_path = outputJSONPathLineEdit->text().toStdString(); request_data_for_saving->output_xpath = outputXPathLineEdit->text().toStdString(); + request_data_for_saving->output_xquery = outputXQueryLineEdit->text().toStdString(); request_data_for_saving->output_regex = outputRegexLineEdit->text().toStdString(); request_data_for_saving->output_regex_flags = outputRegexFlagsLineEdit->text().toStdString();