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"); +} +