tdcommon/src/main/java/thredds/server/catalog/builder/DatasetScanConfigBuilder.java
public DatasetScanConfig readDatasetScanConfig(Element dsElem) {
    DatasetScanConfig result = new DatasetScanConfig();

    result.name = dsElem.getAttributeValue("name");
    result.path = StringUtil2.trim(dsElem.getAttributeValue("path"), '/');
    if (result.path == null) {
      errlog.format("ERROR: must specify path attribute.%n");
      fatalError = true;
    }

    String scanDir = dsElem.getAttributeValue("location");
    if (scanDir == null) {
      errlog.format("ERROR: must specify directory root in location attribute.%n");
      fatalError = true;
    } else {
      result.scanDir = AliasTranslator.translateAlias(scanDir);
      File scanFile = new File(result.scanDir);
      if (!scanFile.exists()) {
        errlog.format("ERROR: directory %s does not exist%n", result.scanDir);
        fatalError = true;
      }
    }

    result.restrictAccess = dsElem.getAttributeValue("restrictAccess");

    // look for ncml
    Element ncmlElem = dsElem.getChild("netcdf", Catalog.defNS);
    if (ncmlElem != null) {
      ncmlElem.detach();
      result.ncmlElement = ncmlElem;
    }

    // Read filter element
    Element filterElem = dsElem.getChild("filter", Catalog.defNS);
    result.filters = readDatasetScanFilter(filterElem);

    // Read namer element
    Element namerElem = dsElem.getChild("namer", Catalog.defNS);
    result.namers = readDatasetScanNamer(namerElem);

    // Read filesSort or sort element
    Element filesSortElem = dsElem.getChild("filesSort", Catalog.defNS);
    if (filesSortElem != null)
      result.isSortIncreasing = readFilesSort(filesSortElem);
    Element sorterElem = dsElem.getChild("sort", Catalog.defNS);
    if (!result.isSortIncreasing.isPresent() && sorterElem != null)
      result.isSortIncreasing = readSort(sorterElem);

    // Deal with latest
    String addLatestAttribute = dsElem.getAttributeValue("addLatest");
    Element addLatestElem = dsElem.getChild("addLatest", Catalog.defNS);      // not in docs
    Element addProxiesElem = dsElem.getChild("addProxies", Catalog.defNS);
    result.addLatest = readDatasetScanAddProxies(addProxiesElem, addLatestElem, addLatestAttribute);

    /* Read addDatasetSize element.
    Element addDsSizeElem = dsElem.getChild("addDatasetSize", Catalog.defNS);
    if (addDsSizeElem != null) {                                               // docs: default true
      if (addDsSizeElem.getTextNormalize().equalsIgnoreCase("false"))
        result.addDatasetSize = false;
    } */

    // Read addTimeCoverage element.
    Element addTimeCovElem = dsElem.getChild("addTimeCoverage", Catalog.defNS);
    if (addTimeCovElem != null) {
      result.addTimeCoverage = readDatasetScanAddTimeCoverage(addTimeCovElem);
    }

    return result;
  }
public DatasetScanConfig readDatasetScanConfig(Element dsElem) {
    DatasetScanConfig result = new DatasetScanConfig();

    result.name = dsElem.getAttributeValue("name");
    result.path = StringUtil2.trim(dsElem.getAttributeValue("path"), '/');
    if (result.path == null) {
      errlog.format("ERROR: must specify path attribute.%n");
      fatalError = true;
    }

    String scanDir = dsElem.getAttributeValue("location");
    if (scanDir == null) {
      errlog.format("ERROR: must specify directory root in location attribute.%n");
      fatalError = true;
    } else {
      result.scanDir = AliasTranslator.translateAlias(scanDir);
      File scanFile = new File(result.scanDir);
      if (!scanFile.exists()) {
        errlog.format("ERROR: directory %s does not exist%n", result.scanDir);
        fatalError = true;
      }
    }

    result.restrictAccess = dsElem.getAttributeValue("restrictAccess");

    // look for ncml
    Element ncmlElem = dsElem.getChild("netcdf", Catalog.defNS);
    if (ncmlElem != null) {
      ncmlElem.detach();
      result.ncmlElement = ncmlElem;
    }

    // Read filter element
    Element filterElem = dsElem.getChild("filter", Catalog.defNS);
    result.filters = readDatasetScanFilter(filterElem);

    // Read namer element
    Element namerElem = dsElem.getChild("namer", Catalog.defNS);
    result.namers = readDatasetScanNamer(namerElem);

    // Read filesSort or sort element
    Element filesSortElem = dsElem.getChild("filesSort", Catalog.defNS);
    if (filesSortElem != null)
      result.isSortIncreasing = readFilesSort(filesSortElem);
    Element sorterElem = dsElem.getChild("sort", Catalog.defNS);
    if (!result.isSortIncreasing.isPresent() && sorterElem != null)
      result.isSortIncreasing = readSort(sorterElem);

    // Deal with latest
    String addLatestAttribute = dsElem.getAttributeValue("addLatest");
    Element addLatestElem = dsElem.getChild("addLatest", Catalog.defNS);      // not in docs
    Element addProxiesElem = dsElem.getChild("addProxies", Catalog.defNS);
    result.addLatest = readDatasetScanAddProxies(addProxiesElem, addLatestElem, addLatestAttribute);

    /* Read addDatasetSize element.
    Element addDsSizeElem = dsElem.getChild("addDatasetSize", Catalog.defNS);
    if (addDsSizeElem != null) {                                               // docs: default true
      if (addDsSizeElem.getTextNormalize().equalsIgnoreCase("false"))
        result.addDatasetSize = false;
    } */

    // Read addTimeCoverage element.
    Element addTimeCovElem = dsElem.getChild("addTimeCoverage", Catalog.defNS);
    if (addTimeCovElem != null) {
      result.addTimeCoverage = readDatasetScanAddTimeCoverage(addTimeCovElem);
    }

    return result;
  }
/*
<xsd:element name="datasetScan" substitutionGroup="dataset">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="DatasetType">
<xsd:sequence>
<xsd:element ref="filter" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="namer" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="sort" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="addLatest" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="addProxies" minOccurs="0" maxOccurs="1"/>
<xsd:element name="addDatasetSize" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="addTimeCoverage" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>

<xsd:attribute name="path" type="xsd:string" use="required"/>
<xsd:attribute name="location" type="xsd:string"/>
<xsd:attribute name="addLatest" type="xsd:boolean"/>
<xsd:attribute name="filter" type="xsd:string"/> <!-- deprecated : use filter element -->
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>