diff --git a/cdm/core/src/main/java/ucar/nc2/internal/ncml/NcmlReader.java b/cdm/core/src/main/java/ucar/nc2/internal/ncml/NcmlReader.java
index df76a96854..cb55b68a26 100644
--- a/cdm/core/src/main/java/ucar/nc2/internal/ncml/NcmlReader.java
+++ b/cdm/core/src/main/java/ucar/nc2/internal/ncml/NcmlReader.java
@@ -288,7 +288,7 @@ public static NetcdfDataset.Builder mergeNcml(NetcdfFile ref, @Nullable Element
if (ncmlElem != null) {
NcmlReader reader = new NcmlReader();
- reader.readGroup(targetDS, null, null, ncmlElem);
+ reader.readGroup(targetDS, null, ref.getRootGroup(), ncmlElem);
}
setEnhanceMode(targetDS, ncmlElem, null);
@@ -574,9 +574,12 @@ private Group.Builder readGroup(NetcdfDataset.Builder builder, @Nullable Group.B
Group refGroup = null;
if (parent == null) {
- refGroup = this.refFile == null ? null : this.refFile.getRootGroup();
+ if (this.refFile != null) {
+ refGroup = this.refFile.getRootGroup();
+ } else if (refParent != null) {
+ refGroup = refParent;
+ }
groupBuilder = builder.rootGroup;
-
} else {
String name = groupElem.getAttributeValue("name");
if (name == null) {
diff --git a/cdm/core/src/test/data/ncml/modifyNestedGroups.xml b/cdm/core/src/test/data/ncml/modifyNestedGroups.xml
new file mode 100644
index 0000000000..5e23c2a646
--- /dev/null
+++ b/cdm/core/src/test/data/ncml/modifyNestedGroups.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/cdm/core/src/test/data/testModifyNestedGroups.nc4 b/cdm/core/src/test/data/testModifyNestedGroups.nc4
new file mode 100644
index 0000000000..3685d9538b
Binary files /dev/null and b/cdm/core/src/test/data/testModifyNestedGroups.nc4 differ
diff --git a/cdm/core/src/test/java/ucar/nc2/internal/ncml/TestNcmlReader.java b/cdm/core/src/test/java/ucar/nc2/internal/ncml/TestNcmlReader.java
index 00f307cacd..3509a10ff3 100644
--- a/cdm/core/src/test/java/ucar/nc2/internal/ncml/TestNcmlReader.java
+++ b/cdm/core/src/test/java/ucar/nc2/internal/ncml/TestNcmlReader.java
@@ -10,6 +10,8 @@
import org.jdom2.input.SAXBuilder;
import org.junit.Test;
import ucar.ma2.Array;
+import ucar.nc2.Attribute;
+import ucar.nc2.Group;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;
import ucar.nc2.dataset.NetcdfDataset;
@@ -25,8 +27,9 @@ public class TestNcmlReader {
public void shouldMergeNcml() throws IOException, JDOMException {
final String filename = TestDir.cdmLocalTestDataDir + "example1.nc";
- try (NetcdfFile netcdfFile = NetcdfDatasets.openFile(filename, null)) {
- final NetcdfDataset netcdfDataset = NcmlReader.mergeNcml(netcdfFile, getNcmlElement("modifyVars.xml")).build();
+ try (NetcdfFile netcdfFile = NetcdfDatasets.openFile(filename, null);
+ final NetcdfDataset netcdfDataset =
+ NcmlReader.mergeNcml(netcdfFile, getNcmlElement("modifyVars.xml")).build();) {
final Variable ncmlVariable = netcdfDataset.findVariable("deltaLat");
assertThat((Object) ncmlVariable).isInstanceOf(VariableDS.class);
@@ -40,9 +43,9 @@ public void shouldMergeNcml() throws IOException, JDOMException {
public void shouldMergeNcmlWithEnhancements() throws IOException, JDOMException {
final String filename = TestDir.cdmLocalTestDataDir + "example1.nc";
- try (NetcdfFile netcdfFile = NetcdfDatasets.openFile(filename, null)) {
- final NetcdfDataset netcdfDataset =
- NcmlReader.mergeNcml(netcdfFile, getNcmlElement("enhance/testStandardizer.ncml")).build();
+ try (NetcdfFile netcdfFile = NetcdfDatasets.openFile(filename, null);
+ final NetcdfDataset netcdfDataset =
+ NcmlReader.mergeNcml(netcdfFile, getNcmlElement("enhance/testStandardizer.ncml")).build();) {
final Variable ncmlVariable = netcdfDataset.findVariable("doublevar");
assertThat((Object) ncmlVariable).isNotNull();
@@ -51,6 +54,49 @@ public void shouldMergeNcmlWithEnhancements() throws IOException, JDOMException
}
}
+ @Test
+ public void mergeWithExistingGroups() throws IOException, JDOMException {
+ final String filename = TestDir.cdmLocalTestDataDir + "testModifyNestedGroups.nc4";
+
+ try (NetcdfFile netcdfFile = NetcdfDatasets.openFile(filename, null);
+ final NetcdfDataset netcdfDataset =
+ NcmlReader.mergeNcml(netcdfFile, getNcmlElement("modifyNestedGroups.xml")).build()) {
+
+ final Group ncmlOuterGroup = netcdfDataset.findGroup("/outer_group");
+ assertThat(ncmlOuterGroup).isNotNull();
+
+ final Attribute ncmlOuterAttribute = ncmlOuterGroup.findAttribute("new_outer_attr");
+ assertThat(ncmlOuterAttribute).isNotNull();
+ assertThat(ncmlOuterAttribute.getStringValue()).isNotNull();
+ assertThat(ncmlOuterAttribute.getStringValue()).isEqualTo("new_outer_attr_value");
+
+ final Variable ncmlOuterVar = ncmlOuterGroup.findVariableLocal("lat");
+ assertThat(ncmlOuterVar != null).isTrue();
+ assertThat(ncmlOuterVar.attributes().hasAttribute("new_lat_attr")).isTrue();
+ assertThat(ncmlOuterVar.attributes().findAttribute("new_lat_attr")).isNotNull();
+ assertThat(ncmlOuterVar.attributes().findAttribute("new_lat_attr").getStringValue()).isNotNull();
+ assertThat(ncmlOuterVar.attributes().findAttribute("new_lat_attr").getStringValue())
+ .isEqualTo("new_lat_attr_value");
+ //
+
+ final Group ncmlInnerGroup = netcdfDataset.findGroup("/outer_group/inner_group");
+ assertThat(ncmlInnerGroup).isNotNull();
+
+ final Attribute ncmlInnerAttribute = ncmlInnerGroup.findAttribute("new_inner_attr");
+ assertThat(ncmlInnerAttribute).isNotNull();
+ assertThat(ncmlInnerAttribute.getStringValue()).isNotNull();
+ assertThat(ncmlInnerAttribute.getStringValue()).isEqualTo("new_inner_attr_value");
+
+ final Variable ncmlInnerVar = ncmlInnerGroup.findVariableLocal("lon");
+ assertThat(ncmlInnerVar != null).isTrue();
+ assertThat(ncmlInnerVar.attributes().hasAttribute("new_lon_attr")).isTrue();
+ assertThat(ncmlInnerVar.attributes().findAttribute("new_lon_attr")).isNotNull();
+ assertThat(ncmlInnerVar.attributes().findAttribute("new_lon_attr").getStringValue()).isNotNull();
+ assertThat(ncmlInnerVar.attributes().findAttribute("new_lon_attr").getStringValue())
+ .isEqualTo("new_lon_attr_value");
+ }
+ }
+
private static Element getNcmlElement(String filename) throws IOException, JDOMException {
final String ncml = TestNcmlRead.topDir + filename;
diff --git a/cdm/core/src/test/java/ucar/nc2/ncml/TestNcmlReadersCompare.java b/cdm/core/src/test/java/ucar/nc2/ncml/TestNcmlReadersCompare.java
index 307d6c135e..890b485ad9 100644
--- a/cdm/core/src/test/java/ucar/nc2/ncml/TestNcmlReadersCompare.java
+++ b/cdm/core/src/test/java/ucar/nc2/ncml/TestNcmlReadersCompare.java
@@ -78,6 +78,9 @@ public boolean accept(File pathname) {
// NcMLReader does not change variable to type int, so fails.
if (name.contains("aggSynthetic.xml"))
return false;
+ // Simulates a TDS datasetScan using NcML and does not fully define a dataset.
+ if (name.contains("modifyNestedGroups.xml"))
+ return false;
// Bug in old reader
if (name.contains("testStandaloneNoEnhance.ncml"))
return false;