cdm/src/main/java/thredds/client/catalog/builder/CatalogBuilder.java
protected void readThreddsMetadataGroup(Map<String,Object> flds, DatasetBuilder dataset, Element parent) {
    List<Element> list;

    // look for creators - kind of a Source
    list = parent.getChildren("creator", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Creators, readSource(e));
    }

    // look for contributors
    list = parent.getChildren("contributor", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Contributors, readContributor(e));
    }

    // look for dates
    list = parent.getChildren("date", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Dates, readDate(e, null));
    }

    // look for documentation
    list = parent.getChildren("documentation", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Documentation, readDocumentation(e));
    }

    // look for keywords - kind of a controlled vocabulary
    list = parent.getChildren("keyword", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Keywords, readControlledVocabulary(e));
    }

    // look for metadata elements
    list = parent.getChildren("metadata", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.MetadataOther, readMetadata(flds, dataset, e));
    }

    // look for projects - kind of a controlled vocabulary
    list = parent.getChildren("project", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Projects, readControlledVocabulary(e));
    }

    // look for properties
    list = parent.getChildren("property", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Properties, readProperty(e));
    }

    // look for publishers - kind of a Source
    list = parent.getChildren("publisher", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Publishers, readSource(e));
    }

    // look for variables
    list = parent.getChildren("variables", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.VariableGroups, readVariables(e));
    }

    // can only be one each of these kinds
    ThreddsMetadata.GeospatialCoverage gc = readGeospatialCoverage(parent.getChild("geospatialCoverage", Catalog.defNS));
    if (gc != null) {
      flds.put(Dataset.GeospatialCoverage, gc);
    }

    DateRange tc = readTimeCoverage(parent.getChild("timeCoverage", Catalog.defNS));
    if (tc != null) {
      flds.put(Dataset.TimeCoverage, tc);
    }

    Element serviceNameElem = parent.getChild("serviceName", Catalog.defNS);
    if (serviceNameElem != null) {
      flds.put(Dataset.ServiceName, serviceNameElem.getText());
    }

    Element authElem = parent.getChild("authority", Catalog.defNS);
    if (authElem != null) {
      flds.put(Dataset.Authority, authElem.getText());
    }

    Element dataTypeElem = parent.getChild("dataType", Catalog.defNS);
    if (dataTypeElem != null) {
      String dataTypeName = dataTypeElem.getText();
      flds.put(Dataset.FeatureType, dataTypeName);
      if ((dataTypeName != null) && (dataTypeName.length() > 0)) {
        FeatureType dataType = FeatureType.getType(dataTypeName.toUpperCase());
        if (dataType == null) {
          errlog.format(" ** warning: non-standard feature type = '%s'%n", dataTypeName);
          logger.debug(" ** warning: non-standard feature type = '{}'", dataTypeName);
        }
      }
    }

    Element dataFormatElem = parent.getChild("dataFormat", Catalog.defNS);
    if (dataFormatElem != null) {
      String dataFormatTypeName = dataFormatElem.getText();
      if ((dataFormatTypeName != null) && (dataFormatTypeName.length() > 0)) {
        DataFormatType dataFormatType = DataFormatType.getType(dataFormatTypeName);
        if (dataFormatType == null) {
          errlog.format(" ** warning: non-standard dataFormat type = '%s'%n", dataFormatTypeName);
          logger.debug(" ** warning: non-standard dataFormat type = '{}'", dataFormatTypeName);
        }
        flds.put(Dataset.DataFormatType, dataFormatTypeName);
      }
    }

    long size = readDataSize(parent);
    if (size > 0) {
      flds.put(Dataset.DataSize, size);
    }

    // LOOK: we seem to have put a variableMap element not contained by <variables>
    ThreddsMetadata.UriResolved mapUri = readUri(parent.getChild("variableMap", Catalog.defNS), "variableMap");
    if (mapUri != null) {
      flds.put(Dataset.VariableMapLinkURI, mapUri);
    }
  }
protected void readThreddsMetadataGroup(Map<String,Object> flds, DatasetBuilder dataset, Element parent) {
    List<Element> list;

    // look for creators - kind of a Source
    list = parent.getChildren("creator", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Creators, readSource(e));
    }

    // look for contributors
    list = parent.getChildren("contributor", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Contributors, readContributor(e));
    }

    // look for dates
    list = parent.getChildren("date", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Dates, readDate(e, null));
    }

    // look for documentation
    list = parent.getChildren("documentation", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Documentation, readDocumentation(e));
    }

    // look for keywords - kind of a controlled vocabulary
    list = parent.getChildren("keyword", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Keywords, readControlledVocabulary(e));
    }

    // look for metadata elements
    list = parent.getChildren("metadata", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.MetadataOther, readMetadata(flds, dataset, e));
    }

    // look for projects - kind of a controlled vocabulary
    list = parent.getChildren("project", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Projects, readControlledVocabulary(e));
    }

    // look for properties
    list = parent.getChildren("property", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Properties, readProperty(e));
    }

    // look for publishers - kind of a Source
    list = parent.getChildren("publisher", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.Publishers, readSource(e));
    }

    // look for variables
    list = parent.getChildren("variables", Catalog.defNS);
    for (Element e : list) {
      DatasetBuilder.addToList(flds, Dataset.VariableGroups, readVariables(e));
    }

    // can only be one each of these kinds
    ThreddsMetadata.GeospatialCoverage gc = readGeospatialCoverage(parent.getChild("geospatialCoverage", Catalog.defNS));
    if (gc != null) {
      flds.put(Dataset.GeospatialCoverage, gc);
    }

    DateRange tc = readTimeCoverage(parent.getChild("timeCoverage", Catalog.defNS));
    if (tc != null) {
      flds.put(Dataset.TimeCoverage, tc);
    }

    Element serviceNameElem = parent.getChild("serviceName", Catalog.defNS);
    if (serviceNameElem != null) {
      flds.put(Dataset.ServiceName, serviceNameElem.getText());
    }

    Element authElem = parent.getChild("authority", Catalog.defNS);
    if (authElem != null) {
      flds.put(Dataset.Authority, authElem.getText());
    }

    Element dataTypeElem = parent.getChild("dataType", Catalog.defNS);
    if (dataTypeElem != null) {
      String dataTypeName = dataTypeElem.getText();
      flds.put(Dataset.FeatureType, dataTypeName);
      if ((dataTypeName != null) && (dataTypeName.length() > 0)) {
        FeatureType dataType = FeatureType.getType(dataTypeName.toUpperCase());
        if (dataType == null) {
          errlog.format(" ** warning: non-standard feature type = '%s'%n", dataTypeName);
          logger.debug(" ** warning: non-standard feature type = '{}'", dataTypeName);
        }
      }
    }

    Element dataFormatElem = parent.getChild("dataFormat", Catalog.defNS);
    if (dataFormatElem != null) {
      String dataFormatTypeName = dataFormatElem.getText();
      if ((dataFormatTypeName != null) && (dataFormatTypeName.length() > 0)) {
        DataFormatType dataFormatType = DataFormatType.getType(dataFormatTypeName);
        if (dataFormatType == null) {
          errlog.format(" ** warning: non-standard dataFormat type = '%s'%n", dataFormatTypeName);
          logger.debug(" ** warning: non-standard dataFormat type = '{}'", dataFormatTypeName);
        }
        flds.put(Dataset.DataFormatType, dataFormatTypeName);
      }
    }

    long size = readDataSize(parent);
    if (size > 0) {
      flds.put(Dataset.DataSize, size);
    }

    // LOOK: we seem to have put a variableMap element not contained by <variables>
    ThreddsMetadata.UriResolved mapUri = readUri(parent.getChild("variableMap", Catalog.defNS), "variableMap");
    if (mapUri != null) {
      flds.put(Dataset.VariableMapLinkURI, mapUri);
    }
  }
/*
<!-- group of elements can be used in a dataset or in metadata elements -->
<xsd:group name="threddsMetadataGroup">
<xsd:choice>
<xsd:element name="documentation" type="documentationType"/>
<xsd:element ref="metadata"/>
<xsd:element ref="property"/>

<xsd:element ref="contributor"/>
<xsd:element name="creator" type="sourceType"/>
<xsd:element name="date" type="dateTypeFormatted"/>
<xsd:element name="keyword" type="controlledVocabulary"/>
<xsd:element name="project" type="controlledVocabulary"/>
<xsd:element name="publisher" type="sourceType"/>

<xsd:element ref="geospatialCoverage"/>
<xsd:element name="timeCoverage" type="timeCoverageType"/>
<xsd:element ref="variables"/>
<xsd:element ref="variableMap"/>

<xsd:element name="dataType" type="dataTypes"/>
<xsd:element name="dataFormat" type="dataFormatTypes"/>
<xsd:element name="serviceName" type="xsd:string"/>
<xsd:element name="authority" type="xsd:string"/>
<xsd:element ref="dataSize"/>
</xsd:choice>
</xsd:group>