diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e85e4da77..ff7afea445 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -51,6 +51,7 @@ file. Slightly modified the FunctionalTestJigsawBundleXYZ ctest accordingly. Iss
- Fixed a bug in isisminer in which bad (e.g. self-intersecting) polygon geometries were not treated properly. Added pertinent unit tests to GisGeometry and Strategy classes. Issue: [5612](https://github.com/DOI-USGS/ISIS3/issues/5612)
- Fixed a bug in kaguyasp2isis that doesn't work for data with a detached label.
- Fixed FunctionalTestCamstatsDefaultParameters test by increasing the runtime speed [#5459](https://github.com/DOI-USGS/ISIS3/issues/5459)
+- Fixed XmlToJson namespaced key conversion [#5652](https://github.com/DOI-USGS/ISIS3/pull/5652)
## [8.3.0] - 2024-09-30
diff --git a/isis/src/base/objs/XmlToJson/XmlToJson.cpp b/isis/src/base/objs/XmlToJson/XmlToJson.cpp
index 428d28526f..88471305be 100644
--- a/isis/src/base/objs/XmlToJson/XmlToJson.cpp
+++ b/isis/src/base/objs/XmlToJson/XmlToJson.cpp
@@ -93,6 +93,7 @@ namespace Isis {
* @param element A QDomElement to be converted to JSON and added to the JSON object.
*/
json convertLastChildNodeToJson(QDomElement& element){
+ std::string cleanTagName = element.tagName().replace(":", "_").toStdString();
json newJson;
if (element.hasAttributes()) {
// If there are attributes, add them
@@ -108,17 +109,17 @@ namespace Isis {
if (!element.text().isEmpty()) {
attributeSection["_text"] = element.text().toStdString();
}
- newJson[element.tagName().replace(":", "_").toStdString()] = attributeSection;
+ newJson[cleanTagName] = attributeSection;
}
else {
// Just add element and its value
// value
if (!element.text().isEmpty()) {
- newJson[element.tagName().replace(":", "_").toStdString()] = element.text().toStdString();
+ newJson[cleanTagName] = element.text().toStdString();
}
else {
// no value case
- newJson[element.tagName().replace(":", "_").toStdString()];
+ newJson[cleanTagName];
}
}
return newJson;
@@ -147,23 +148,24 @@ namespace Isis {
*/
json convertXmlToJson(QDomElement& element, json& output) {
while (!element.isNull()) {
+ std::string cleanTagName = element.tagName().replace(":", "_").toStdString();
QDomElement next = element.firstChildElement();
if (next.isNull()){
json converted = convertLastChildNodeToJson(element);
// Simple case with no repeated tags at the same level
- if (!output.contains(element.tagName().toStdString())){
+ if (!output.contains(cleanTagName)){
output.update(converted);
}
else {
// There is a repeated tag at the same level in the XML, i.e: val1val2
// Translated json goal: a:[val1, val2]
// If the converted json has an array already, append, else make it an array
- if (!output[element.tagName().toStdString()].is_array()) {
+ if (!output[cleanTagName].is_array()) {
json repeatedArray;
repeatedArray.push_back(output[element.tagName().toStdString()]);
- output[element.tagName().replace(":", "_").toStdString()] = repeatedArray;
+ output[cleanTagName] = repeatedArray;
}
- output[element.tagName().replace(":", "_").toStdString()].push_back(converted[element.tagName().toStdString()]);
+ output[cleanTagName].push_back(converted[cleanTagName]);
}
}
else {
@@ -172,16 +174,16 @@ namespace Isis {
// overwriting. This is the following situation:
// XML: value1 value2
// JSON: a: [ {first:value1, second:value2} ]
- if (output.contains(element.tagName().toStdString())) {
+ if (output.contains(cleanTagName)) {
// If it's an array already, append, else make it an array
json temporaryJson;
convertXmlToJson(next, temporaryJson);
- if (!output[element.tagName().toStdString()].is_array()) {
+ if (!output[cleanTagName].is_array()) {
json repeatedArray;
repeatedArray.push_back(output[element.tagName().toStdString()]);
- output[element.tagName().replace(":", "_").toStdString()] = repeatedArray;
+ output[cleanTagName] = repeatedArray;
}
- output[element.tagName().replace(":", "_").toStdString()].push_back(temporaryJson);
+ output[cleanTagName].push_back(temporaryJson);
}
else {
if (element.hasAttributes()) {
@@ -192,12 +194,12 @@ namespace Isis {
tempArea["attrib_"+attr.name().toStdString()] = attr.value().toStdString();
}
tempArea.update(
- convertXmlToJson(next, output[element.tagName().toStdString()]));
- output[element.tagName().replace(":", "_").toStdString()] = tempArea;
+ convertXmlToJson(next, output[cleanTagName]));
+ output[cleanTagName] = tempArea;
}
else {
- output[element.tagName().toStdString()] =
- convertXmlToJson(next, output[element.tagName().replace(":", "_").toStdString()]);
+ output[cleanTagName] =
+ convertXmlToJson(next, output[cleanTagName]);
}
}
}
diff --git a/isis/tests/XmlToJsonTests.cpp b/isis/tests/XmlToJsonTests.cpp
index 2d3906e3dd..b20f60ffa1 100644
--- a/isis/tests/XmlToJsonTests.cpp
+++ b/isis/tests/XmlToJsonTests.cpp
@@ -254,4 +254,42 @@ TEST(XmlToJson, TestXMLEverythingTogether) {
EXPECT_EQ(result["TagLevel0"]["TagLevel1B"]["Third"]["Greek"]["AnotherLevel"]["Gamma"]["_text"], "GammaValue");
}
+// This tests that all the sub-pieces tested above work together in a single XMl document
+TEST(XmlToJson, TestXMLWithNamespace) {
+ QString xmlInput = R"(
+
+
+
+ eis000xxx_2032116t234928_0000c35f-wac-pushb-img_raw
+ display_settings_to_array
+
+
+ Sample
+ Left to Right
+ Line
+ Top to Bottom
+
+
+
+ 27.54
+
+
+ )";
+
+ QDomDocument xmlDocument("TestDocument");
+ xmlDocument.setContent(xmlInput);
+ json result = xmlToJson(xmlDocument);
+
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["Local_Internal_Reference"]["local_identifier_reference"], "eis000xxx_2032116t234928_0000c35f-wac-pushb-img_raw");
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["Local_Internal_Reference"]["local_reference_type"], "display_settings_to_array");
+
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["disp_Display_Direction"]["disp_horizontal_display_axis"], "Sample");
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["disp_Display_Direction"]["disp_horizontal_display_direction"], "Left to Right");
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["disp_Display_Direction"]["disp_vertical_display_axis"], "Line");
+ EXPECT_EQ(result["Discipline_Area"]["disp_Display_Settings"]["disp_Display_Direction"]["disp_vertical_display_direction"], "Top to Bottom");
+
+ EXPECT_EQ(result["Discipline_Area"]["img_Exposure"]["img_exposure_duration"]["_text"], "27.54");
+ EXPECT_EQ(result["Discipline_Area"]["img_Exposure"]["img_exposure_duration"]["attrib_unit"], "ms");
+}
+